一、前言
Canal
是阿里的一款开源我的项目,纯 Java
开发。基于数据库增量日志解析,提供增量数据订阅 & 生产,目前次要反对了 MySQL
(也反对 mariaDB
)。
Canal
除了反对 binlog
实时 增量同步 数据库之外也反对 全量同步,本文次要分享应用 Canal 来实现从 MySQL 到 Elasticsearch 的全量同步;
可通过应用 adapter
的 REST
接口手动触发 ETL
工作,实现全量同步。
在执行全量同步的时候,同一个
destination
的增量同步工作会被 阻塞 ,待全量同步实现被阻塞的增量同步会被 从新唤醒
PS:对于 Canal 的部署与 实时同步 请看文章《Canal 高可用架构部署》
二、ETL 接口
adapter
的 ETL
接口为:/etl/{type}/{task}
- 默认 web 端口为
8081
- type 为类型(hbase/es7/rdb)
- task 为工作名对应配置文件名,如 sys_user.yml
例子:
curl -X POST http://127.0.0.1:8081/etl/es7/sys_user.yml
执行胜利输入:
{"succeeded":true,"resultMessage":"导入 ES 数据:17 条"}
三、实际过程中遇到的坑
3.1. 连接池不够
当同步的数据量比拟大时,执行一段时间后会呈现下图的谬误
3.1.1. 起因剖析
查看 canal
源码得悉当同步的数据量大于 1w 时,会分批进行同步,每批 1w 条记录,并应用多线程来并行执行工作,而 adapter
默认的连接池为 3,当线程获取数据库连贯期待超过 1 分钟就会抛出该异样。
线程数为以后服务器 cpu 的可用线程数
3.1.2. 解决形式
批改 adapter
的 conf/application.yml
文件中的 srcDataSources
配置项,减少 maxActive
配置数据库的最大连接数为以后服务器 cpu 的可用线程数
cpu 线程数能够下命令查看
grep 'processor' /proc/cpuinfo | sort -u | wc -l
3.2. es 连贯超时
当同步的表字段比拟多时,几率呈现以下报错
3.2.1. 起因剖析
因为 adapter
的表映射配置文件中的 commitBatch
提交批大小设置过大导致(6000)
3.2.2. 解决形式
批改 adapter
的 conf/es7/xxx.yml
映射文件中的 commitBatch
配置项为 3000
3.3. 同步慢
三千万的数据量用时 3.5 小时左右
3.3.1. 起因剖析
因为当数据量大于 1w 时 canal
会对数据进行分批同步,每批 1w 条通过分页查问实现;所以当数据量较大时会呈现深分页的状况导致查问十分慢。
3.3.2. 解决形式
事后应用 ID、工夫或者业务字段等进行数据分批后再进行同步,缩小每次同步的数据量。
3.3.3. 案例
应用 ID 进行数据分批,适宜增长类型的 ID,如自增 ID、雪花 ID 等;
- 查出 最小 ID、最大 ID 与 总数据量
- 依据每批数据量大小计算每批的 ID 区间
计算过程:
- 最小 ID = 1333224842416979257
- 最大 ID = 1341698897306914816
- 总数据量 = 3kw
- 每次同步量 = 300w
(1) 计算同步的次数
总数据量 / 每次同步量 = 10
(2) 计算每批 ID 的增量值
(最大 ID - 最小 ID) / 次数 = 847405488993555.9
(3) 计算每批 ID 的值
最小 ID + 增量值 = ID2
ID2 + 增量值 = ID3
...
ID9 + 增量值 = 最大 ID
(4) 应用分批的 ID 值进行同步
批改 sql 映射配置,的 etlCondition
参数:
etlCondition: "where id >= {} and id < {}"
调用 etl 接口,并减少 params
参数,多个参数之间应用 ;
宰割
curl -X POST http://127.0.0.1:8081/etl/es7/sys_user.yml?params= 最小 ID;ID2
curl -X POST http://127.0.0.1:8081/etl/es7/sys_user.yml?params=ID2;ID3
...
扫码关注有惊喜!