一、環境要求
1.1 操作系統
- Canal 是由 Java 開發,Windows/Linux 均可支持。
- 不同的 Canal 版本所需的 JDK 版本亦不同,下表展示了它們之間關係。
Canal JDK 1.1.4 1.8 1.1.0 ~ 1.1.3 1.7 1.0.19 ~ 1.0.25 1.6
1.2 MySQL 要求
-
目前 Canal 已支持 MySQL 5.7.13/5.6.10 及以下的版本,MariaDB 5.5.35 和 10.0.7(理論上可支持以下版本)。
-
Canal 的原理是基於 MySQL binlog 複製技術,所以這裏一定需要開啓 MySQL 的 binlog 寫入功能,建議配置 binlog 模式爲 row(ps. 目前 Canal 已經支持 mixed/statement/row 模式) 。配置 my.cnf:
[mysql] log-bin=mysql-bin #添加這一行就 ok binlog-format=ROW #選擇 row 模式 server_id=1 #配置 mysql replaction 需要定義,不能和canal的slaveId重複
可在 mysql 控制檯通過執行下述命令查看變更結果。
show variables like 'binlog_format%'
-
Canal 的原理是把自己模擬成 MySQL Slave,所以這裏一定需要爲 canal 使用的用戶在數據庫賦相關權限。
CREATE USER canal IDENTIFIED BY 'canal'; GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%'; -- GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%' ; FLUSH PRIVILEGES;
針對已有的賬戶,可通過 grants 查詢權限:
show grants for 'canal';
二、獲取發佈包
發佈包可直接在 Canal 的官方社區下載,當前最新版本爲:canal.deployer-1.1.4.tar.gz。
2.1 下載安裝包
通常情況下,社區每發佈一個版本,都會將把發佈的版本程序封裝成安裝包,訪問 https://github.com/alibaba/canal/releases 會列出所有發佈的歷史版本安裝包。以 1.1.4 版本爲例:
canal.adapter-1.1.4.tar.gz # 全組件安裝包
canal.admin-1.1.4.tar.gz # 管理端安裝包
canal.deployer-1.1.4.tar.gz # server安裝包
canal.example-1.1.4.tar.gz # 客戶端示例程序
Source code(zip) # zip 壓縮方式的源碼
Source code(tar.gz) # tar.gz 壓縮方式的源碼
2.2 自行編譯
該方式需要編程工具 IDE 、git 的支持,請具備一定 Java 編程基礎並熱衷源碼研究的人採用此方式。如下僅簡略描述一下關鍵步驟。
git clone https://github.com/alibaba/canal.git
git checkout canal-$version # 切換到對應的版本上
mvn clean install -Denv=release # 在deployer目錄下執行
執行完成後,會在 deployer 模塊下生成一個 target 目錄,裏面會包含一個:canal.deployer-$version.tar.gz。
三、創建用戶及配置環境變量
創建用戶和配置環境變量其實是可選項,讀者可忽略該小節。只是筆者慣於將各不同的服務進行環境隔離,以降低誤操作的可能性。
-
創建用戶
最好不要直接使用 root 用戶,當然用 root 也是可以的,只是生產環境沒人這麼幹,太危險了。如果你不知道怎麼取名, 就跟我一樣用 canal 這個用戶吧。請使用擁有 root 權限的用戶執行下述命令:useradd canal # 創建名爲 canal 的用戶 passwd canal # 修改 canal 用戶的密碼
-
創建 canal 服務的安裝根目錄
Canal 服務的安裝目錄其實也可以自行定義,只是筆者慣於將數據文件夾放到 /data 下面,程序文件夾放到 /usr/local 下面。請使用擁有 root 權限的用戶執行下述命令:mkdir /usr/local/canal # 創建canal安裝目錄 chown canal:canal /usr/local/canal # 更改目錄所有者
-
配置環境變量
環境變量其實也是可選配置項,如果不配置,則每次操作 canal 服務時,需要追加絕對路徑,爲了後續操作的便利性,所以此處爲其配置環境變量。vi /home/canal/.bashrc
把下述信息追加到文本中。
export CANAL_HOME=/usr/local/canal export PATH=$PATH:$CANAL_HOME/bin
注意:CANAL_HOME 的值爲 canal 的安裝根目錄,若你未將程序放在 /usr/local/canal 目錄下,請將該值調整爲你的實際目錄。
使用
:wq
保存退出後,再用下述命令讓配置生效。source /home/canal/.bashrc
四、單節點模式部署
從此小節開始至文末,請皆使用 canal 用戶操作。
-
上傳、解壓
先把 Canal 安裝包上傳至指定服務器上(具體命令略),再將安裝包解壓到 /usr/local/canal 目錄中。tar -zxvf canal.deployer-1.1.4.tar.gz -C /usr/local/canal
解壓完成之後,進入 /usr/local/canal 目錄,可以看到如下結構:
drwxrwxr-x. 2 canal canal 4096 May 30 12:27 bin drwxrwxr-x. 6 canal canal 4096 May 30 12:27 conf drwxrwxr-x. 2 canal canal 4096 May 6 12:27 lib drwxrwxr-x. 9 canal canal 4096 May 30 12:27 logs
-
修改配置
進入到 canal 的安裝目錄 /usr/local/canal 下,編輯打開 instance 名爲 example 的配置文件:vi conf/example/instance.properties
example 僅是爲 instance 起的一個別名,該名稱可自定義;當需要定義多個 instance 時,可參考 conf/example 文件夾的範式,在相同的目錄下複製多個與 conf/example 僅名稱不同的文件夾,且文件夾裏的文件也應相同。再把 instance 名稱(即剛創建的文件夾名)追加到 conf/canal.properties 文件的 canal.destinations 屬性值中,多個值之間以英文半角的逗號分隔。
僅需要修改如下 3 個屬性值,爲 canal 指定需要同步數據的目標數據庫的連接信息即可:
canal.instance.master.address=127.0.0.1:3306 canal.instance.dbUsername=root canal.instance.dbPassword=123456
如果你定義了多個目標庫,請爲每個目標庫修改其對應的連接信息。
-
啓動或停止
如果已經成功配置了環境變量信息,則可在任意目錄下執行下述命令啓動或停止 canal 服務。startup.sh # 啓動 stop.sh # 停止
-
驗證啓動狀態
tail -f log/canal/canal.log # 查閱服務的日誌信息
2020-06-02 11:26:13.159 [main] INFO com.alibaba.otter.canal.deployer.CanalLauncher - ## set default uncaught exception handler 2020-06-02 11:26:13.206 [main] INFO com.alibaba.otter.canal.deployer.CanalLauncher - ## load canal configurations 2020-06-02 11:26:13.220 [main] INFO com.alibaba.otter.canal.deployer.CanalStarter - ## start the canal server. 2020-06-02 11:26:13.263 [main] INFO com.alibaba.otter.canal.deployer.CanalController - ## start the canal server[127.0.0.1(127.0.0.1):11111] 2020-06-02 11:26:13.264 [main] INFO com.alibaba.otter.canal.deployer.CanalLauncher - ## the canal server is running now ......
日誌中顯示類似於如上信息,則表示 canal 服務啓動成功。
tail -f log/example/example.log # 查閱instance日誌
2020-06-02 11:37:18.102 [main] INFO c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [canal.properties] 2020-06-02 11:37:18.105 [main] INFO c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [example/instance.properties] 2020-06-02 11:37:18.301 [main] INFO c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [canal.properties] 2020-06-02 11:37:18.301 [main] INFO c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [example/instance.properties] 2020-06-02 11:37:18.697 [main] INFO c.a.otter.canal.instance.spring.CanalInstanceWithSpring - start CannalInstance for 1-example 2020-06-02 11:37:18.713 [main] INFO c.a.otter.canal.instance.core.AbstractCanalInstance - start successful....
日誌中顯示類似於如上信息,則表示 canal 的 instance 啓動成功。
五、高可用(HA)模式部署
-
角色規劃
角色 機器 Canal Server 158.220.71.138、158.220.71.139 ZooKeeper 158.222.189.90 MySQL 158.222.188.206 -
配置
本文僅以 instance 名稱爲 example 示例。-
conf/canal.properties
請參照下述示例爲 canal 指定 binlog 位置信息存儲方式爲 zooKeeper。canal.zkServers=158.222.189.90:2181 # 指定zookeeper服務地址 canal.instance.global.spring.xml = classpath:spring/default-instance.xml
Canal 默認的 binlog 位置信息存儲方式是本地文件,此處爲了實現高可用,需要將其變更爲 zookeeper 方式,即將 canal.instance.global.spring.xml 的屬性值變更爲 classpath:spring/default-instance.xml。
-
conf/example/instance.properties
canal.instance.mysql.slaveId = 1234 # 取值範圍爲正整數,需保證各slaveId不重複即可 canal.instance.master.address = 158.222.188.206:3306
注意:兩個 canal 服務的配置信息,唯一不同的地方僅是 slaveId。
-
-
啓動
在兩臺機器上分別使用startup.sh
命令啓動 canal 服務。通過查看 zookeeper 中的節點信息,可獲知當前工作的節點。[zk: localhost:2181(CONNECTED) 1] get /otter/canal/destinations/example/running {"active":true,"address":"158.220.71.138:11111","cid":1}
當前工作的節點是:158.220.71.138:11111。
-
連接客戶端
客戶端可以直接指定 zookeeper 地址和 instance name,其會自動從 zookeeper 中的 running 節點,獲取當前正在提供服務的節點信息,然後與其建立連接:CanalConnector connector = CanalConnectors.newClusterConnector("158.222.189.90:2181", "example", "", "");
連接成功後,canal server 會記錄當前正在提供服務的 canal client 信息,比如客戶端 ip,連接的端口信息等(聰明的你,應該也可以發現,canal client 也可以支持 HA 功能)。
[zk: localhost:2181(CONNECTED) 2] get /otter/canal/destinations/example/1001/running {"active":true,"address":"158.220.142.204:50544","clientId":1001}
數據消費成功後,canal server 會在 zookeeper 中記錄下當前最後一次消費成功的 binlog 位點(下次你重啓 client 時,會從這最後一個位點繼續進行消費)。
[zk: localhost:2181(CONNECTED) 3] get /otter/canal/destinations/example/1001/cursor {"@type":"com.alibaba.otter.canal.protocol.position.LogPosition","identity":{"slaveId":-1,"sourceAddress":{"address":"158.222.188.206","port":3306}},"postion":{"included":false,"journalName":"mysql-bin.002253","position":2574756,"timestamp":1363688722000}}
-
觸發切換
正常情況下觸發 canal server 主備切換的有如下兩種方式:-
正常關閉:通過在正在運行 158.220.71.38 機器上執行
stop.sh
命令停止 canal server,則會釋放 instance 的所有資源,包括刪除 running 節點。 -
平滑切換:在 zk 中更新對應 instance 的 running 節點內容,將"active"設置爲 false,對應的 running 節點收到消息後,會主動釋放 running 節點,讓出控制權但自己的 JVM 不退出。可在 zookeeper 查到的信息爲:
{"active":false,"address":"158.220.71.138:11111","cid":1}
當位於 158.220.71.139 節點上處於 stanby 狀態的 canal server 監測到的該狀態變化,或 running 節點不存在時,會立馬啓動 example instance,提供新的服務。
[zk: localhost:2181(CONNECTED) 4] get /otter/canal/destinations/example/running {"active":true,"address":"158.220.71.139:11111","cid":1}
與此同時,客戶端也會隨着 canal server 的切換,通過獲取 zookeeper 中的最新地址,與新的 canal server 建立鏈接,繼續消費數據,整個過程自動完成。
-
六、MySQL 多節點解析配置
-
MySQL 機器準備
準備兩個 MySQL 服務,配置爲 M-M 模式。本文的 MySQL 示例 IP 和 port 地址爲:158.220.71.140:3306、158.222.71.141:3306。[mysqld] log_slave_updates=true # 這個配置一定要打開
-
修改配置
參照下述內容修改 conf/canal.properties 文件中的配置信息:# position info canal.instance.master.address = 158.220.71.140:3306 canal.instance.standby.address = 158.220.71.141:3306 # 需要開啓心跳檢查 canal.instance.detecting.enable = true # 心跳檢查SQL,也可以選擇類似 select 1 的查詢語句 canal.instance.detecting.sql = insert into retl.xdual values(1,now()) on duplicate key update x=now() # 心跳檢查頻率 canal.instance.detecting.interval.time = 3 # 心跳檢查失敗次數閾值,超過該閾值後會觸發 MySQL 連接切換,比如切換到 standby 機器上繼續解析 binlog canal.instance.detecting.retry.threshold = 3 # 心跳檢查超過失敗次數閥值後,是否開啓 master/standby 的切換 canal.instance.detecting.heartbeatHaEnable = true
注意:
- 填寫 master/standby 的地址,當前僅支持配置一個 standby。
- 發生 master/standby 的切換的條件:(heartbeatHaEnable = true) && (失敗次數>=retry.threshold)。
- 多引入一個 heartbeatHaEnable 的考慮:開啓心跳 sql 有時候是爲 client 檢測 canal server 是否正常工作,如果定時收到了心跳語句,那說明整個 canal server 工作正常。
-
啓動 & 測試
關閉一臺機器的 MySQL,在經歷大概 interval.time * retry.threshold 時間後,就會切換到 standby 機器上。