什麼是 canal#
canal,譯意為水道 / 管道 / 溝渠,主要用途是基於 MySQL 資料庫增量日誌解析,提供 增量資料訂閱和消費。
通常情況下,canal 用來同步或監控 MySQL 資料庫的資料,比如資料入庫後同步到 ES
canal 將自己偽裝成 MySQL 的從機,解析並處理主機發送的 binary log 日誌
配置 canal#
在使用 canal 之前,你需要配置本地的 MySQL 服務,使其啟用 binlog 日誌
window 找到安裝 MySQL 目錄下的 my.ini
文件,把下面的配置加入到 [mysqld]
下
#binlog文件名
log-bin=mysql-bin
#選擇row模式
binlog_format=ROW
#mysql實例id,不能和canal的slaveId重複
server_id=1
Linux 可直接修改
vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin # 開啟binlog
binlog-format=ROW # 選擇ROW模式
server_id=1 # 配置MySQL replaction需要定義,不和Canal的slaveId重複即可
配置完成後重啟 MySQL 服務
使用以下命令查看是否啟用成功
show variables like 'log_bin';
然後在官方倉庫下載最新版並解壓
修改 conf
文件夾下的 canal.properties
不修改使用默認也行
其中重要的是
# 指定接口
canal.port = 11111
# 指定實例
canal.destinations = example
# 指定模式,默認tcp,其它有kafka, rocketMQ, rabbitMQ, pulsarMQ
canal.serverMode = tcp
# 指定rabbitmq,不配置使用默認tcp也行
rabbitmq.host =
rabbitmq.virtual.host =
rabbitmq.exchange =
rabbitmq.username =
rabbitmq.password =
rabbitmq.deliveryMode =
然後修改 example
(對應上面的實例配置) 下的 instance.properties
# 主機地址
canal.instance.master.address=127.0.0.1:3306
# 連接主機的賬戶名密碼
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
# 指定連接時的編碼
canal.instance.connectionCharset = UTF-8
# 指定監聽的資料庫與表,此配置代表監聽test庫下的全部表
canal.instance.filter.regex=test..*
配置完成後在 bin
目錄下使用 startup.bat
啟動 canal
此時就代表啟動成功了
spring boot 配置#
在 spring boot 中使用 canal 有以下幾種方式
- 使用官方依賴
- 使用第三方
倉庫 | 版本 | 優劣 |
---|---|---|
https://github.com/alibaba/canal | 官方 | 配置簡單,實現困難 |
https://github.com/NormanGyllenhaal/canal-client | 第三方 | 簡單易用,斷更,有 BUG |
https://github.com/behappy-project/behappy-canal | 第三方 | 上面的改版,持續更新,缺點僅支持 jdk17+ |
https://github.com/xizixuejie/canal-spring | 第三方 | 簡單易用,持續更新 |
推薦使用最後一個
在 maven 中添加依賴
<dependency>
<groupId>io.github.xizixuejie</groupId>
<artifactId>canal-spring-boot-starter</artifactId>
<version>0.0.5</version>
</dependency>
在配置文件中註冊
# canal服務地址
canal.server=127.0.0.1:11111
# canal的集群名字,要與安裝canal時設置的名稱一致
canal.destination=example
# 未配置也使用默認的tcp模式,但未配置可能會無法監聽到,因此推薦配置
canal.server-mode=tcp
完成後在啟動類增加
@EnableCanalListener(basePackages = "com.jkkj.config.canal")
開啟監聽器,並指定監聽器的配置路徑
然後配置監聽器
@CanalListener(schemaName = "test", tableName = "testTable")
public class TestListener implements EntryListener<TestEntity> {
private static final Logger log = LoggerFactory.getLogger(TestListener.class);
@Override
public void insert(TestEntity testEntity) {
log.info("insert={}", testEntity);
}
@Override
public void update(TestEntity before, TestEntity after) {
log.info("update before={}", before);
log.info("update after={}", after);
}
@Override
public void delete(TestEntity testEntity) {
log.info("delete={}", testEntity);
}
}
可以使用 @CanalListener
指定庫名及表名
@CanalListener(schemaName = "test", tableName = "testTable")
也可以不指定,則會根據 Entity
對象監聽,這種方式需要在實體類中指定
@TableName(value = "inspection_result_home")
會根據這個 mybatisplus 註解實體類名自動轉換表名
擴展#
在使用過程中,發現如果實體類中字段為下面的情況則會報錯
這是因為在轉換過程中沒有指定解析器
你可以查看我提的這個 Issues,或等待作者修改 (作者已修改)
docker 安裝#
在 Linux 下使用 docker 安裝是比較簡單的
- 下載鏡像
docker pull canal/canal-server:v1.1.5
- 先啟動一次
docker run -p 11111:11111 --name canal -d canal/canal-server:v1.1.5
- 複製配置文件
# 拷貝配置文件
docker cp canal:/home/admin/canal-server/conf/example/instance.properties /home/docker/canal/conf
docker cp canal:/home/admin/canal-server/conf/canal.properties /home/docker/canal/conf
前面為容器內地址,後面的 /home/jk/docker/canal/conf
是宿主機地址
4. 修改配置文件
主要修改的地方為 instance.properties
下的
# 主機地址
canal.instance.master.address=127.0.0.1:3306
127.0.0.1
指代的是容器地址,如果你的 MySQL 安裝在宿主機內,則需要指定宿主機的資料庫地址。使用 ifconfig
命令查看 docker0 就表示宿主機地址
- 重啟鏡像
docker stop canal
docker rm canal
docker run -p 11111:11111 --name canal \
-v /home/jk/docker/canal/conf/instance.properties:/home/admin/canal-server/conf/example/instance.properties \
-v /home/jk/docker/canal/conf/canal.properties:/home/admin/canal-server/conf/canal.properties \
-d canal/canal-server:v1.1.5
不使用最新版本 canal 鏡像的原因可查看此鏈接