今天工作不飽滿,上班時(shí)間閑的無聊,決定學(xué)一下 canal。其實(shí)關(guān)于 canal 的教程在 https://github.com/alibaba/canal/wiki 這里寫的挺清楚的,基本上照著步驟搞就完事了。我寫這個(gè)文章的目的主要是給自己做個(gè)筆記~
1. 準(zhǔn)備 canal server
- 官方下載 canal server,即 https://github.com/alibaba/canal/releases/tag/canal-1.1.4 里面的 canal.deployer-1.1.4.tar.gz 文件
- 解壓到指定目錄
mkdir canal.deployer-1.1.4
tar -xvzf canal.deployer-1.1.4.tar.gz -C canal.deployer-1.1.4
2. 配置 canal server
- 因?yàn)樵嫉?bin/restart.sh 有 bug,只能在 bin 目錄下執(zhí)行才可以,所以修改了一下,修改后完整文件如下
#!/bin/bash
args=$@
SCRIPT_DIR=$(cd "$(dirname "$0")"; pwd)
sh $SCRIPT_DIR/stop.sh $args
sh $SCRIPT_DIR/startup.sh $args
- conf/canal.properties 文件是 canal server 的基礎(chǔ)配置文件,其中有一段代碼如下,各項(xiàng)配置的作用如注釋所說
#################################################
######### destinations #############
#################################################
# 這里定義了 canal server 啟動(dòng)的時(shí)候要添加的 instance 名稱,默認(rèn)是 example
canal.destinations = example
# 這里定義了 canal server 查找 instance 配置文件的根路徑。
# 舉個(gè)例子,假如前面配置了 example instance, 那么 canal server 會(huì)查找 ../conf/example/instance.properties 文件
canal.conf.dir = ../conf
# 這里控制著 canal server 是否在運(yùn)行過程中自動(dòng)掃描 canal.conf.dir 目錄以動(dòng)態(tài)添加或刪除 instance,默認(rèn)打開,掃描時(shí)間間隔 5s
canal.auto.scan = true
canal.auto.scan.interval = 5
- 因?yàn)槲也幌胧褂?example instance, 所以我將 conf/canal.properties 文件修改如下
# 指定 instance 為 content
canal.destinations = content
# 關(guān)閉自動(dòng)掃描 instance, 這樣就可以忽略掉 example instance 了
canal.auto.scan = false
- 為自定義的 content instance 創(chuàng)建配置文件 conf/content/instance.properties
canal.instance.mysql.slaveId = 1234
canal.instance.master.address = 127.0.0.1:3307
canal.instance.dbUsername = root
canal.instance.dbPassword = 123456
canal.instance.defaultDatabaseName = content
canal.instance.connectionCharset = UTF-8
# 這里官方文檔寫的是 canal.instance.filter.regex = .\*\\\\..\*
# 在 TCP 模式下兩者沒有任何區(qū)別,但是在 kafka 模式下只有下面這種寫法生效
# 測(cè)試的過程中發(fā)現(xiàn)了這種現(xiàn)象,但還沒有查清具體原因
canal.instance.filter.regex = .*\\..*
3. 啟動(dòng) canal server
canal server 啟動(dòng)過程中的關(guān)鍵信息如下:
- 確定 binlog first position
(1) 先從 conf/content/meta.dat 文件中查找 last position, 也就是最后一次成功 dump binlog 的位點(diǎn)
(2) 如果不存在 last position, 則從 conf/content/instance.properties 配置文件中查找 initial position, 這是我們?nèi)藶榕渲玫某跏蓟稽c(diǎn)
(3) 如果不存在 initial position, 則執(zhí)行 show master status 命令獲取 mysql binlog lastest position
通過以上三步就可以確定 canal server 啟動(dòng)之后 binlog 初始位點(diǎn) - 將 first position 賦值給 last position 保存在內(nèi)存中
- 將 schema 緩存到 conf/content/h2.mv.db 文件中
4. 啟動(dòng) canal client
- canal client 的 java demo 可以去官方 GitHub 上找一下,記得將 destination 等配置信息改正確。請(qǐng)參考 https://github.com/alibaba/canal/wiki/ClientExample
- canal client connect
- canal client describe
(1) 在收到客戶端訂閱請(qǐng)求之后,logs/content/content.log 文件會(huì)打印出相關(guān)日志
(2) conf/content/meta.dat 文件記錄了客戶端的訂閱信息,包括 clientId, destination, filter 等 - canal client getWithoutAck
(1) canal server 在收到 canal client 查詢請(qǐng)求之后,以內(nèi)存中的 last position 作為參數(shù)向 mysql server 發(fā)送 dump 請(qǐng)求
(2) 如果存在比 last position 更新的 binlog, canal server 會(huì)收到 mysql server 的返回?cái)?shù)據(jù),然后將其轉(zhuǎn)換為 Message 數(shù)據(jù)結(jié)構(gòu)返回給 canal client - canal client ack
canal server 在收到 canal client 確認(rèn)請(qǐng)求之后,更新內(nèi)存中的 last position 并同步保存到 conf/content/meta.dat 文件中,在 logs/content/meta.log 文件中打印日志
5. 補(bǔ)充
- 因?yàn)樵?TCP 模式下,一個(gè) instance 只能有一個(gè) canal client 訂閱,即使同時(shí)有多個(gè) canal client 訂閱相同的 instance, 也只會(huì)有一個(gè) canal client 成功獲取 binlog, 所以 canal server 寫死 clientId = 1001. 也正是因?yàn)橐粋€(gè) instance 只有一個(gè) canal client, 所以 canal server 將 binlog 位點(diǎn)信息維護(hù)在了 instance 級(jí)別,即 conf/content/meta.dat 文件中
- 在 TCP 模式下,如果 canal client 想重新獲取以前的 binlog,只能通過修改 canal server 的 initial position 配置并重啟服務(wù)來達(dá)到目的
- 在 TCP 模式下 canal server 主要提供了兩個(gè)功能
(1) 維護(hù) mysql binlog position 信息,目的是作為 dump 的請(qǐng)求參數(shù),這也是 canal server 唯一保存的數(shù)據(jù)
(2) 對(duì)客戶端提供接口以查詢 binlog