docker快速搭建alibaba-canal
需求來源
跟蹤表對比前後修改數據變化
方案
-
AOP、攔截器
優點: 實現簡單
缺點:
- 代碼入侵性強 每加入一個模塊就需要處理切面添加切入點,模塊配置也需要增加。
- 項目依賴麻煩,檔案模塊需要依賴對應模塊api包進行序列化實現對比,業務模塊需要實現查詢接口。
- 模塊適配插拔式實現困難
- sql解析困難複雜容易出錯(攔截mapper層解析update語句)
-
日誌採集方案
優點:
- 只需要處理數據變化對比,可以直接集成三方插件如es查詢,無代碼入侵。後續擴展強,無論任何任何模塊需要加入類似功能只需要中間件配置,添加log監聽即可。
缺點:
- 需要部署其他服務,增加運維成本,依賴於三方服務可能存在數據丟失
canal部署
環境
這裏使用的是mac os 搭配docker部署,幾乎和linux環境差不多
canal + rocketMQ + ES 實現
基礎同步技術介紹
準備
對於自建 MySQL , 需要先開啓 Binlog 寫入功能,配置 binlog-format 爲 ROW 模式,my.cnf 中配置如下
[mysqld]
log-bin=mysql-bin # 開啓 binlog
binlog-format=ROW # 選擇 ROW 模式
server_id=1 # 配置 MySQL replaction 需要定義,不要和 canal 的 slaveId 重複
注意:針對阿里雲 RDS for MySQL , 默認打開了 binlog , 並且賬號默認具有 binlog dump 權限 , 不需要任何權限或者 binlog 設置,可以直接跳過這一步
授權 canal 鏈接 MySQL 賬號具有作爲 MySQL slave 的權限, 如果已有賬戶可直接 grant
CREATE USER canal IDENTIFIED BY 'canal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
-- GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%' ;
FLUSH PRIVILEGES;
快速啓動參考:QuickStart
其中主要注意配置匹配數據庫、表規則配置,可以選擇匹配部分表做記錄。 也可以通過配置不同的topic消費做消費實現不同的業務。參考文檔:配置 主要關注Topic配置匹配規則
RoketMQ 搭建
docker 使用 foxiswho/rocketmq 鏡像
參考博客
docker run -d -p 10911:10911 -p 10909:10909\
--name rmqbroker --link rmqserver:namesrv\
-e "NAMESRV_ADDR=namesrv:9876" -e "JAVA_OPTS=-Duser.home=/opt"\
-e "JAVA_OPT_EXT=-server -Xms128m -Xmx128m"\
foxiswho/rocketmq:broker-4.5.1
使用上面docker命令拉取鏡像,快速搭建
搭建canal
下載docker啓動文件
linux命令
wget https://github.com/alibaba/canal/blob/master/docker/run.sh
mac 命令
curl -0 https://github.com/alibaba/canal/blob/master/docker/run.sh
配置canal配置項
主要注意配置
# 按需修改成自己的數據庫信息
canal.instance.master.address=192.168.1.20:3306
# username/password,數據庫的用戶名和密碼
canal.instance.dbUsername = canal
canal.instance.dbPassword = canal
# mq config 這個配置使用動態topic就可以不配置,選其一
canal.mq.topic=example
# 針對庫名或者表名發送動態topic,參考配置
#canal.mq.dynamicTopic=mytest,.*,mytest.user,mytest\\..*,.*\\..*
sh run.sh -e canal.auto.scan=false \
-e canal.destinations=test \
-e canal.instance.master.address=172.17.0.7:3306 \
-e canal.instance.dbUsername=admin \
-e canal.instance.dbPassword=123456 \
-e canal.instance.defaultDatabaseName=mytest \
-e canal.instance.connectionCharset=UTF-8 \
-e canal.instance.tsdb.enable=true \
-e canal.instance.gtidon=false \
-e canal.mq.dynamicTopic=mytest:mytest.sg_pop_base_info \
-e canal.mq.partition=0 \
-e canal.serverMode=rocketmq \
-e canal.mq.servers=172.17.0.10:9876 \
-e canal.mq.retries=0 \
-e canal.mq.batchSize=16384 \
-e canal.mq.maxRequestSize=1048576 \
-e canal.mq.lingerMs=200 \
-e canal.mq.bufferMemory=33554432 \
-e canal.mq.canalBatchSize=50 \
-e canal.mq.canalGetTimeout=100 \
-e canal.mq.flatMessage=true \
-e canal.mq.compressionType=none \
-e canal.mq.acks=all \
-e canal.mq.transaction=false
mysql、mq如果使用的容器,注意添加link配置 或者 通過命令docker inspect [容器名] 查看IPAddress配置到配置中
docker查看啓動成功
#運行 docker logs 容器名稱
docker logs canal-server
# 如下表示成功
DOCKER_DEPLOY_TYPE=VM
==> INIT /alidata/init/02init-sshd.sh
==> EXIT CODE: 0
==> INIT /alidata/init/fix-hosts.py
==> EXIT CODE: 0
==> INIT DEFAULT
Generating SSH1 RSA host key: [ OK ]
Starting sshd: [ OK ]
Starting crond: [ OK ]
==> INIT DONE
==> RUN /home/admin/app.sh
==> START ...
start canal ...
start canal successful
==> START SUCCESSFUL ...
有興趣的可以看一下run.sh這個文件,搞過服務器的肯定看得懂,就是各種變量然後組裝docker 的run命令
查看MQ消息
修改監控表數據即可查看mq中消息,如果修改了數據沒有消息,查看canal-server容器中日誌報錯
本地mq客戶端查看消息:http://localhost:8180/#/message
實現技術通過canal獲取日誌拿到對比數據放入MQ,MQ消息數據如下:
新增消息
{
"data": [
{
"id": "111",
"name": "ad ",
"create_date": "2020-04-15 14:31:03",
"update_date": "2020-04-15 14:31:08",
"create_user": "asdf ",
"update_user": "sadf ",
"is_deleted": "0"
}
],
"database": "grid_comm_center",
"es": 1586932274000,
"id": 66,
"isDdl": false,
"mysqlType": {
"id": "bigint(64)",
"name": "varchar(200)",
"create_date": "timestamp",
"update_date": "timestamp",
"create_user": "varchar(32)",
"update_user": "varchar(32)",
"is_deleted": "tinyint(2) unsigned"
},
"old": null,
"pkNames": [
"id"
],
"sql": "",
"sqlType": {
"id": -5,
"name": 12,
"create_date": 93,
"update_date": 93,
"create_user": 12,
"update_user": 12,
"is_deleted": -6
},
"table": "demo_id",
"ts": 1586932275053,
"type": "INSERT"
}
修改消息
{
"data": [
{
"id": "111",
"name": "ad asdf ",
"create_date": "2020-04-15 14:31:03",
"update_date": "2020-04-15 14:31:54",
"create_user": "asdf adf ",
"update_user": "sadf asdf",
"is_deleted": "0"
}
],
"database": "grid_comm_center",
"es": 1586932314000,
"id": 67,
"isDdl": false,
"mysqlType": {
"id": "bigint(64)",
"name": "varchar(200)",
"create_date": "timestamp",
"update_date": "timestamp",
"create_user": "varchar(32)",
"update_user": "varchar(32)",
"is_deleted": "tinyint(2) unsigned"
},
"old": [
{
"name": "ad ",
"update_date": "2020-04-15 14:31:08",
"create_user": "asdf ",
"update_user": "sadf "
}
],
"pkNames": [
"id"
],
"sql": "",
"sqlType": {
"id": -5,
"name": 12,
"create_date": 93,
"update_date": 93,
"create_user": 12,
"update_user": 12,
"is_deleted": -6
},
"table": "demo_id",
"ts": 1586932314983,
"type": "UPDATE"
}
刪除消息
{
"data": [
{
"id": "1111",
"name": "123123",
"create_date": "2020-03-17 17:48:23",
"update_date": "2020-03-17 17:48:26",
"create_user": "你好",
"update_user": "你好",
"is_deleted": "1"
}
],
"database": "grid_comm_center",
"es": 1587366810000,
"id": 1049,
"isDdl": false,
"mysqlType": {
"id": "bigint(64)",
"name": "varchar(200)",
"create_date": "timestamp",
"update_date": "timestamp",
"create_user": "varchar(32)",
"update_user": "varchar(32)",
"is_deleted": "tinyint(2) unsigned"
},
"old": null,
"pkNames": [
"id"
],
"sql": "",
"sqlType": {
"id": -5,
"name": 12,
"create_date": 93,
"update_date": 93,
"create_user": 12,
"update_user": 12,
"is_deleted": -6
},
"table": "demo_id",
"ts": 1587366810548,
"type": "DELETE"
}
如上消息可以清楚拿到數據庫、表詳細變更,通過拿到變更數據解析插入數據庫即可。
官方中還可以通過ClientAdapter 適配器入庫到RDB、HBase、ES,這裏根據需求做部署操作吧。目前這個裏自己做檔案模塊進行消費寫入檔案數據,預計搜索可以放入es可以加快查詢效率。
查看這些消息,然後做消費即可做自己想做的事情,至此已經完成了canal的基礎搭建
消費消息寫入ElasticSearch
maven配置
<elasticsearch.version>7.2.0</elasticsearch.version>
<!-- Java High Level REST Client -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<exclusions>
<exclusion>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</exclusion>
<exclusion>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
</exclusion>
</exclusions>
<version>${elasticsearch.version}</version>
</dependency>
mq使用的是公司封裝的包,所以這裏省略mq相關代碼。直接集成mq消費相關消費做自己業務處理即可。