MySQL CDC技术方案梳理

news2024/11/18 3:00:36

  本篇主要探讨MySQL数据同步的各类常见技术方案及优劣势对比分析,从而更加深层次的理解方案,进而在后续的实际业务中,更好的选择方案。

1 CDC概念

  CDC即Change Data Capture,变更数据捕获,即当数据发生变更时,能够实时或准实时的捕获到数据的变化,以MySQL为例,产生数据变更的操作有insertupdatedelete。CDC技术就时在数据变更时,能够以安全、可靠的方式同步给其他服务、存储,如mongodb、es、kafka、redis、clickhouse等。

2 CDC原理分类

  目前一些常用的组件有alibaba canal,apache flink,go-mysql-transfer等。CDC 的技术方案非常多,目前业界主流的实现机制可以分为两种:

2.1 基于查询的 CDC

  • 离线调度查询作业,批处理。把一张表同步到其他系统,每次通过查询去获取表中最新的数据;
  • 无法保障数据一致性,查的过程中有可能数据已经发生了多次变更;
  • 不保障实时性,基于离线调度存在天然的延迟。

2.2 基于日志的 CDC

  • 实时消费日志,流处理,例如 MySQL 的 binlog 日志完整记录了数据库中的变更,可以把 binlog 文件当作流的数据源;
  • 保障数据一致性,因为 binlog 文件包含了所有历史变更明细;
  • 保障实时性,因为类似 binlog 的日志文件是可以流式消费的,提供的是实时数据。

3 开源方案对比

flink cdcDebeziumCanalSqoopKettleOracle GoldengateGo-mysql-transfer
CDC机制日志日志日志查询查询日志日志
增量同步
全量同步
断点续传
全量 + 增量
架构分布式单机单机分布式分布式分布式单机
Transformation⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️
生态⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️

如上图所示,需要根据实际业务场景,决定使用哪一种开源方案。

4 使用场景

cdc,顾名思义,就是数据变更捕获,其本质是实时获取MySQL数据变更(增删改),进而同步其他服务或者业务方。因此其使用场景主要分为:

  1. 数据分发:将一个数据源的数据分发给多个下游业务系统,常用于业务解耦、微服务系统。
  2. 数据采集:面向数据仓库、数据湖的ETL数据集成,消除数据孤岛,便于后续的分析。
  3. 数据同步:常用于数据备份、容灾等。

5 MySQL配置

5.1 开启MySQL的binlog

[mysqld]
default-storage-engine=INNODB
server-id = 100`唯一`)
port = 3306
log-bin=mysql-bin (`开启`)
binlog_format = ROW (`注意要设置为行模式`

开启之后,在MySQL的数据目录(/usr/local/mysql-8.0.32-macos13-arm64/data),就会生成相应的binlog文件

-rw-r-----    1 _mysql  _mysql      1867  6 12 00:03 mysql-bin.000001
-rw-r-----    1 _mysql  _mysql      5740  6 18 20:55 mysql-bin.000002
-rw-r-----    1 _mysql  _mysql        38  6 12 00:03 mysql-bin.index

查看binlog开启

5.2 创建canal同步账户及权限设置

mysql> CREATE USER canal IDENTIFIED BY 'canal';  
mysql> GRANT SELECT, SHOW VIEW, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
mysql> FLUSH PRIVILEGES;

6 Canal配置

6.1 canal同步kafka原理

原理等同于MySQL的主从复制,具体流程:

  1. canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议
  2. MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
  3. canal 解析 binary log 对象(原始为 byte 流)

6.2 canal安装与配置

具体配置请参考文章 https://www.cnblogs.com/Clera-tea/p/16517424.html

6.2.1 配置文件

/canal/conf/canal.properties

6.2.2 同步kafka配置

canal.serverMode = kafka
##################################################
#########                    Kafka                   #############
##################################################
kafka.bootstrap.servers = 127.0.0.1:9092 (本机kafka服务)
kafka.acks = all
kafka.compression.type = none
kafka.batch.size = 16384
kafka.linger.ms = 1
kafka.max.request.size = 1048576
kafka.buffer.memory = 33554432
kafka.max.in.flight.requests.per.connection = 1
kafka.retries = 0

kafka.kerberos.enable = false
kafka.kerberos.krb5.file = "../conf/kerberos/krb5.conf"
kafka.kerberos.jaas.file = "../conf/kerberos/jaas.conf"

6.2.3 binlog过滤设置

# binlog filter config
canal.instance.filter.druid.ddl = false(注意这里true 改成 false)
canal.instance.filter.query.dcl = false
canal.instance.filter.query.dml = false
canal.instance.filter.query.ddl = false
canal.instance.filter.table.error = false
canal.instance.filter.rows = false
canal.instance.filter.transaction.entry = false
canal.instance.filter.dml.insert = false
canal.instance.filter.dml.update = false
canal.instance.filter.dml.delete = false

6.2.4 同步destinations设置

canal.destinations = example,mytopic(多个逗号分隔)

6.2.5 每个topic都有各自的实例配置

路径/conf/topicname/instance.properties
设置监听mysql地址

canal.instance.master.address=127.0.0.1:3306

配置mysql账户

canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
canal.instance.connectionCharset = UTF-8

配置canal同步到kafka topic信息

canal.mq.topic=mytopic

6.2.6 kafka数据接收

1 mysql
2 zkServer start
3 kafka-server-start /opt/homebrew/etc/kafka/server.properties
4 canal/bin/startup.sh

kafka 消费者收到的消息如下

{
    "data":[
        {
            "id":"22",
            "url":"1",
            "source":"d",
            "status":"1",
            "created_at":"2023-06-29 00:10:31",
            "updated_at":"2023-06-29 00:10:31"
        }
    ],
    "database":"finance",
    "es":1687968631000,
    "id":2,
    "isDdl":false,
    "mysqlType":{
        "id":"int unsigned",
        "url":"varchar(2048)",
        "source":"varchar(32)",
        "status":"tinyint",
        "created_at":"datetime",
        "updated_at":"datetime"
    },
    "old":null,
    "pkNames":[
        "id"
    ],
    "sql":"",
    "sqlType":{
        "id":4,
        "url":12,
        "source":12,
        "status":-6,
        "created_at":93,
        "updated_at":93
    },
    "table":"f_collect",
    "ts":1687968631537,
    "type":"INSERT"
}
{
    "data":[
        {
            "id":"22",
            "url":"1",
            "source":"d",
            "status":"100",
            "created_at":"2023-06-29 00:10:31",
            "updated_at":"2023-06-29 00:31:39"
        }
    ],
    "database":"finance",
    "es":1687969899000,
    "id":3,
    "isDdl":false,
    "mysqlType":{
        "id":"int unsigned",
        "url":"varchar(2048)",
        "source":"varchar(32)",
        "status":"tinyint",
        "created_at":"datetime",
        "updated_at":"datetime"
    },
    "old":[
        {
            "status":"1",
            "updated_at":"2023-06-29 00:10:31"
        }
    ],
    "pkNames":[
        "id"
    ],
    "sql":"",
    "sqlType":{
        "id":4,
        "url":12,
        "source":12,
        "status":-6,
        "created_at":93,
        "updated_at":93
    },
    "table":"f_collect",
    "ts":1687969899293,
    "type":"UPDATE"
}
{
    "data":[
        {
            "id":"22",
            "url":"1",
            "source":"d",
            "status":"100",
            "created_at":"2023-06-29 00:10:31",
            "updated_at":"2023-06-29 00:31:39"
        }
    ],
    "database":"finance",
    "es":1687969946000,
    "id":4,
    "isDdl":false,
    "mysqlType":{
        "id":"int unsigned",
        "url":"varchar(2048)",
        "source":"varchar(32)",
        "status":"tinyint",
        "created_at":"datetime",
        "updated_at":"datetime"
    },
    "old":null,
    "pkNames":[
        "id"
    ],
    "sql":"",
    "sqlType":{
        "id":4,
        "url":12,
        "source":12,
        "status":-6,
        "created_at":93,
        "updated_at":93
    },
    "table":"f_collect",
    "ts":1687969946443,
    "type":"DELETE"
}

7 go-mysql-transfer配置

7.1 基本说明

项目github地址:go-mysql-transfer

  1. 简单,不依赖其它组件,一键部署
  2. 集成多种接收端,如:Redis、MongoDB、Elasticsearch、RocketMQ、Kafka、RabbitMQ、HTTP API等,无需编写客户端,开箱即用
  3. 内置丰富的数据解析、消息生成规则、模板语法
  4. 支持Lua脚本扩展,可处理复杂逻辑
  5. 集成Prometheus客户端,支持监控告警
  6. 集成Web Admin监控页面
  7. 支持高可用集群部署
  8. 数据同步失败重试
  9. 支持全量数据初始化

7.2 原理

  1. 将自己伪装为MySQL的Slave监听binlog,获取binlog的变更数据
  2. 根据规则或者lua脚本解析数据,生成指定格式的消息
  3. 将生成的消息批量发送给接收端

7.3 安装

1、依赖Golang 1.14 及以上版本
2、设置' GO111MODULE=on '
3、拉取源码 ' git clone https://github.com/wj596/go-mysql-transfer.git '
4、进入目录,执行 ' go build ' 编译

7.4 全量数据同步

./go-mysql-transfer -stock

7.5 配置文件app.yaml

都能看懂,不做详细说明,主要配置项

1. mysql
2. target (kafka)
3. kafka配置
4. rule
	4.1 数据库,表,字段
	4.2 lua_file_path: lua/sync.lua 可以只配置基本的数据格式,也可以配置lua脚本来调整数据格式
	4.3 kafka topic
# mysql配置
addr: 127.0.0.1:3306
user: #mysql用户名
pass: #mysql密码
charset : utf8
slave_id: 1001 #slave ID
flavor: mysql #mysql or mariadb,默认mysql

#系统相关配置
#data_dir: D:\\transfer #应用产生的数据存放地址,包括日志、缓存数据等,默认当前运行目录下store文件夹
#logger:
#  level: info #日志级别;支持:debug|info|warn|error,默认info

#maxprocs: 50 #并发协(线)程数量,默认为: CPU核数*2;一般情况下不需要设置此项
#bulk_size: 1000 #每批处理数量,不写默认100,可以根据带宽、机器性能等调整;如果是全量数据初始化时redis建议设为1000,其他接收端酌情调大

#prometheus相关配置
#enable_exporter: true #是否启用prometheus exporter,默认false
#exporter_addr: 9595 #prometheus exporter端口,默认9595

#web admin相关配置
enable_web_admin: true #是否启用web admin,默认false
web_admin_port: 8060 #web监控端口,默认8060

#cluster: # 集群相关配置
  #name: myTransfer #集群名称,具有相同name的节点放入同一个集群
  #bind_ip: 127.0.0.1 # 绑定的IP,如果机器有多张网卡(包含虚拟网卡)会有多个IP,使用这个属性绑定一个
  #ZooKeeper地址,多个用逗号风格
  #zk_addrs: 192.168.1.10:2181,192.168.1.11:2182,192.168.1.12:2183
  #zk_authentication: 123456 #digest类型的访问秘钥,如:user:password,默认为空
  #etcd_addrs: 127.0.0.1:2379 #etcd连接地址,多个用逗号分隔
  #etcd_user: test #etcd用户名
  #etcd_password: 123456 #etcd密码

#目标类型
target: kafka # 支持redis、mongodb、elasticsearch、rocketmq、kafka、rabbitmq

#redis连接配置
#redis_addrs: 127.0.0.1:6379 #redis地址,多个用逗号分隔
#redis_group_type: cluster   # 集群类型 sentinel或者cluster
#redis_master_name: mymaster # Master节点名称,如果group_type为sentinel则此项不能为空,为cluster此项无效
#redis_pass: 123456 #redis密码
#redis_database: 0  #redis数据库 0-16,默认0。如果group_type为cluster此项无效

#mongodb连接配置
#mongodb_addrs: 127.0.0.1:27017 #mongodb连接地址,多个用逗号分隔
#mongodb_username: #mongodb用户名,默认为空
#mongodb_password: #mongodb密码,默认为空

#elasticsearch连接配置
#es_addrs: 127.0.0.1:9200 #连接地址,多个用逗号分隔
#es_version: 7 # Elasticsearch版本,支持6和7、默认为7
#es_password:  # 用户名
#es_version:  # 密码

#rocketmq连接配置
#rocketmq_name_servers: 127.0.0.1:9876 #rocketmq命名服务地址,多个用逗号分隔
#rocketmq_group_name: transfer_test_group #rocketmq group name,默认为空
#rocketmq_instance_name: transfer_test_group_ins #rocketmq instance name,默认为空
#rocketmq_access_key: RocketMQ #访问控制 accessKey,默认为空
#rocketmq_secret_key: 12345678 #访问控制 secretKey,默认为空

#kafka连接配置
kafka_addrs: 127.0.0.1:9092 #kafka连接地址,多个用逗号分隔
#kafka_sasl_user:  #kafka SASL_PLAINTEXT认证模式 用户名
#kafka_sasl_password: #kafka SASL_PLAINTEXT认证模式 密码

#rabbitmq连接配置
#rabbitmq_addr: amqp://guest:guest@127.0.0.1:5672/  #连接字符串,如: amqp://guest:guest@localhost:5672/

#规则配置
rule:
  -
    schema: test #数据库名称
    table: score #表名称
    #order_by_column: id #排序字段,存量数据同步时不能为空
    #column_lower_case:false #列名称转为小写,默认为false
    #column_upper_case:false#列名称转为大写,默认为false
    column_underscore_to_camel: false #列名称下划线转驼峰,默认为false
    # 包含的列,多值逗号分隔,如:id,name,age,area_id  为空时表示包含全部列
    include_columns: ID,name,age,sex
    #exclude_columns: BIRTHDAY,MOBIE # 排除掉的列,多值逗号分隔,如:id,name,age,area_id  默认为空
    #column_mappings: USER_NAME=account    #列名称映射,多个映射关系用逗号分隔,如:USER_NAME=account 表示将字段名USER_NAME映射为account
    #default_column_values: area_name=合肥  #默认的列-值,多个用逗号分隔,如:source=binlog,area_name=合肥
    #date_formatter: yyyy-MM-dd #date类型格式化, 不填写默认yyyy-MM-dd
    #datetime_formatter: yyyy-MM-dd HH:mm:ss #datetime、timestamp类型格式化,不填写默认yyyy-MM-dd HH:mm:ss
    lua_file_path: lua/sync.lua   #lua脚本文件,项目目录创建lua目录
    #lua_script:   #lua 脚本
    value_encoder: json  #值编码,支持json、kv-commas、v-commas;默认为json
    #value_formatter: '{{.ID}}|{{.USER_NAME}}' # 值格式化表达式,如:{{.ID}}|{{.USER_NAME}},{{.ID}}表示ID字段的值、{{.USER_NAME}}表示USER_NAME字段的值

    #redis相关
    redis_structure: string # 数据类型。 支持string、hash、list、set、sortedset类型(与redis的数据类型一致)
    #redis_key_prefix: USER_ #key的前缀
    #redis_key_column: USER_NAME #使用哪个列的值作为key,不填写默认使用主键
    #redis_key_formatter: '{{.ID}}|{{.USER_NAME}}'
    #redis_key_value: user #KEY的值(固定值);当redis_structure为hash、list、set、sortedset此值不能为空
    #redis_hash_field_prefix: _CARD_ #hash的field前缀,仅redis_structure为hash时起作用
    #redis_hash_field_column: Cert_No #使用哪个列的值作为hash的field,仅redis_structure为hash时起作用,不填写默认使用主键
    #redis_sorted_set_score_column: id #sortedset的score,当数据类型为sortedset时,此项不能为空,此项的值应为数字类型

    #mongodb相关
    #mongodb_database: transfer #mongodb database不能为空
    #mongodb_collection: transfer_test_topic #mongodb collection,可以为空,默认使用表名称

    #elasticsearch相关
    #es_index: user_index #Index名称,可以为空,默认使用表(Table)名称
    #es_mappings: #索引映射,可以为空,为空时根据数据类型自行推导ES推导
    #  -
    #    column: REMARK #数据库列名称
    #    field: remark #映射后的ES字段名称
    #    type: text #ES字段类型
    #    analyzer: ik_smart #ES分词器,type为text此项有意义
    #    #format: #日期格式,type为date此项有意义
    #  -
    #    column: USER_NAME #数据库列名称
    #    field: account #映射后的ES字段名称
    #    type: keyword #ES字段类型

    #rocketmq相关
    #rocketmq_topic: transfer_test_topic #rocketmq topic,可以为空,默认使用表名称

    #kafka相关
    kafka_topic: test #rocketmq topic,可以为空,默认使用表名称

    #rabbitmq相关
    #rabbitmq_queue: user_topic #queue名称,可以为空,默认使用表(Table)名称

    #reserve_raw_data: true #保留update之前的数据,针对rocketmq、kafka、rabbitmq有用;默认为false

7.6 项目启动

1. 启动zk(zkServer.sh)
2. 启动kafka (kafka-server-start.sh server.properties)
3. 启动go-mysql-transfer (./go-mysql-transfer)
4. 启动kafka消费者(kafka-console-consumer --bootstrap-server 127.0.0.1:9092 --topic test)
5. 编写简单的lua脚本,实现数据同步
6. 验证数据同步

go-mysql-transfer/lua/sync.lua脚本内容

local json = require("json")   -- 加载json模块
local ops = require("mqOps") --加载mq操作模块
local os = require("os") --加载os模块

local row = ops.rawRow()  --当前数据库的一行数据,
local action = ops.rawAction()  --当前数据库事件,包括:insert、updare、delete

local id = row["id"] --获取ID列的值
local name = row["name"]
local age = row["age"]
local sex = row["sex"]

local result = {}
local data = {}

result["timestamp"] = os.time()
result["action"] = action

data['id'] = id
data['name'] = name
data['age'] = age
data['sex'] = sex

result["object"] = data

local val = json.encode(result) -- 将result转为json
ops.SEND("test", val) -- 发送消息,参数1:topic(string类型),参数2:消息内容

启动go-mysql-transfer
在这里插入图片描述
mysql更新数据
在这里插入图片描述

kafka收到的消息
在这里插入图片描述

常见问题汇总

  1. The Cluster ID i0yMUA_eRHuBS60eM1ph9w doesn’t match stored clusterId Some(aH
    https://blog.csdn.net/m0_59252007/article/details/119533700

参考文档

1 https://www.kancloud.cn/wj596/go-mysql-transfer/2116628
2 https://www.cnblogs.com/Clera-tea/p/16517424.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/734169.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu: scp命令使用及Permission denied错误解决方案

scp命令介绍 scp 命令用于 Linux 之间复制文件和目录。scp 是 secure copy 的缩写, scp 是 Ubuntu 系统下基于 ssh 登陆进行安全的远程文件拷贝命令。 scp local_file remote_usernameremote_ip:remote_folder scp /Users/X.pem root192.168.1.247:/usr/local/ssl Permission…

java项目之高校校园点餐系统(ssm+mysql+jsp)

风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的闲一品交易平台。技术交流和部署相关看文末! 开发环境: 后端: 开发语言:Java 框架&#…

傻瓜式一键生成主子表

文章目录 傻瓜式一键生成主子表 简介创建主子表示例 根据已有主表创建子表示例 创建空属性主子表示例 总结 傻瓜式一键生成主子表 直接将xml导入到Studio里即可。下载文件连接: CSDN链接阿里云盘 简介 很多同学在创建主子表时,都会可能遇到如下一些问…

日本留学托福要求多少分才及格呢?

日本有悠久的历史和文化,吸引了越来越多的留学生前往探索和学习。那么,日本留学托福要求多少分才及格呢? 日本留学托福成绩要求 综合类:通常要求申请者取得托福总分在80以上,各项分数要求分别为口语20以上&#xff0c…

LinuxI2C应用编程——I2C-Tools的使用

文章目录 I2C 硬件框架I2C 软件框架I2C协议(传输数据的格式)写操作读操作I2C 信号 SMBus 协议概述硬件和软件上的区别SMBus 协议分析符号的含义SMBus Quick CommandSMBus Receive ByteSMBus Send ByteSMBus Read ByteSMBus Read WordSMBus Write ByteSMB…

11_Linux阻塞与非阻塞

目录 阻塞和非阻塞IO简介 等待队列 等待队列头 等待队列项 轮询 Linux驱动下的poll操作函数 阻塞式访问IO实验 阻塞式访问IO驱动程序编写 运行测试 非阻塞式IO实验 运行测试 阻塞和非阻塞IO简介 阻塞和非阻塞IO是Linux驱动开发里面很常见的两种设备访问模式,在编写…

充分利用测试自动化的 10 个最佳实践

目录 前言: 实践1:手动和自动测试结合 实践2:特别注意回归测试 实践3:包括端到端测试 实践4:为自动化测试提供集体所有权 实践5:详细计划与测试相关的所有流程 实践6:选择适合您需求的自…

Python随机生成2堆三维点云点,有固定的重复率并可视化

Python随机生成2堆三维点云点,有固定的重复率并可视化 1. 效果图2. 源码 这篇博客源于博友的提问,刚好电脑在旁边没啥事,那就开整吧。 np.random 生成随机点(提供了俩种方法,1. xyz限制都是0~MAX值,2. xyz分…

IDEA中使用.env文件配置信息

一、说明 我们以配置阿里云的 Access Key 的信息为例(配置别的信息当然也可以,我只是举个例子!!!),假设我们的代码中需要用到它。Access Key有两个属性,分别为【ALIBABA_CLOUD_ACCE…

【剧前爆米花--前端三剑客】html的一些常用标签及其实例

作者:困了电视剧 专栏:《JavaEE初阶》 文章分布:这是一篇关于html前端的文章,在这篇文章中我会简单介绍一些常用的html标签,并给出他们的应用实例,希望对你有所帮助! 目录 html常见标签 标题标…

python_day3_tuple

元组tuple :无法修改(只读的列表) t1 () t2 tuple() t3 (1, java, True, ()) print(f"t1的数据类型是:{type(t1)}") print(f"t2的数据类型是:{type(t2)}") print(f"t3的数据类型是&#…

ChatLaw:北大团队智能法律助手,国产大模型成功应用普惠法律服务

“ 技术发展的本质是普惠,用技术降低普通人获取法律知识的成本,向社会输出普惠的公平正义。—— 北京大学 ChatLaw 项目组” 刚刚清华团队升级了国产大模型:ChatGLM2-6B,ChatGLM2-6B 初体验。 转眼这两天北大团队推出的智能法律助…

DAY36:贪心算法(三)最大子数组和+买卖股票最佳时机

文章目录 53.最大子数组和枚举思路暴力解法贪心思路完整版时间复杂度 122.买卖股票的最佳时机Ⅱ(解法比较巧妙)思路完整版总结 53.最大子数组和 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元…

Java开发基础系列(一):Java设计概述

😊 作者: 一恍过去 💖 主页: https://blog.csdn.net/zhuocailing3390 🎊 社区: Java技术栈交流 🎉 主题: Java开发基础系列(一):Java设计概述 ⏱️ 创作时间: 2023年…

【漏洞复现】nginxWebUI 存在前台远程命令执行漏洞

文章目录 前言声明一、nginxWebUI 简介二、漏洞描述三、影响版本四、漏洞复现五、修复建议 前言 nginxWebUI 存在前台远程命令执行漏洞,攻击者通过该漏洞获取服务器控制权限进而进一步获取敏感数据信息。 声明 请勿利用文章内的相关技术从事非法测试,由…

# 文盘Rust -- FFI 浅尝

作者: jiashiwen 原文来源: https://tidb.net/blog/cfa03c39 notice"Rust is a trademark of the Mozilla Foundation in the US and other countries." rust FFI 是rust与其他语言互调的桥梁,通过FFI rust 可以有效继承 C 语言…

道德与社会问题简报 #4: 文生图模型中的偏见

简而言之: 我们需要更好的方法来评估文生图模型中的偏见 介绍 文本到图像 (TTI) 生成 现在非常流行,成千上万的 TTI 模型被上传到 Hugging Face Hub。每种模态都可能受到不同来源的偏见影响,这就引出了一个问题: 我们如何发现这些模型中的偏见&#xff1…

Android启动流程优化 上篇

Android启动流程优化 上篇 本文链接:Android启动流程优化 上篇_猎羽的博客-CSDN博客 启动流程 各个阶段图 1、各个阶段的概括总结 分为5个大阶段或者10个小阶段 【字节跳动团队】内部论坛分享也是这么处理的 补充一些只是细节点: application#onCreate()运行…

基于多案例系统学习防洪评价报告编制方法与水流数学模型建模(HECRAS、MIKE、EFDC、Delft3D、FVCOM、SWAT、SWMM等模型应用)

目录 ​专题一 《防洪评价报告编制导则解读河道管理范围内建设项目编制导则》(SL/T808- 2021)解读编制导则解读 专题二 防洪评价相关制度与解析 ★专题三 案例演练解析 专题四 防洪评价地形获取及常用计算实践 专题五 HEC-RAS软件原理及应用案例解析…

leetcode160.相交链表

https://leetcode.cn/problems/intersection-of-two-linked-lists/solution/ 相交链表是指两个单向链表在某个节点处相交,之后形成了共同的后续部分。通常,两个链表的长度不相等。在相交节点之前,两个链表的节点数可能不同,但在相…