canal原理的一些学习-2(HA 模式搭建)
簡介
??本篇主要介紹canal的HA集群的搭建過程,以及結合自身使用過程的一些經歷介紹一些注意事項。
- 簡介
- 1. 集群的搭建
- 1.1 機器準備
- 1.2 在兩臺canal機器上完成以下配置
- 1.2.1 修改canal.properties
- 1.2.2 新建對應的destionation
- 2. 集群原理的解釋
- 2.1 啟動的時候決定誰為master
- 2.2 運行過程中的HA切換
- 2.3 客戶端的HA切換
- 3. 實際中運用的一些經驗總結
- 3.1 如何讓運行起來的canal(HA模式)恢復到初始狀態。
- 3.2 canal 連接的數據庫是slave,無法獲取到master的binlog的情況
- 3.3 canal版本預警
- 4 對應的canal的配置
- 5.canal的HA客戶端使用
1. 集群的搭建
??HA集群主要使用zookeeper來作為一些metadata的存儲基地,以便于滿足集群信息的共享。下面我們開始介紹集群搭建的步驟。
1.1 機器準備
mysql: 10.29.15.227:3316 用戶:user_canal 密碼:pass_canal canal: 10.29.26.172 10.29.18.29 zookeeper: 10.29.17.46:2181,10.29.18.29:2181,10.29.26.172:21811.2 在兩臺canal機器上完成以下配置
1.2.1 修改canal.properties
canal.zkServers=10.20.144.51:2181 canal.instance.global.spring.xml = classpath:spring/default-instance.xml1.2.2 新建對應的destionation
注意每個destionation 對應的是一個mysql實例
mkdir test_canal_db修改對應的instance.properties文件(該文件從example/instance.properties拷貝而來)
canal.instance.mysql.slaveId = 1234 ##另外一臺機器改成1235,保證slaveId不重復即可 canal.instance.master.address = 10.29.61.119:3315注意: 兩臺機器上的instance目錄的名字需要保證完全一致,HA模式是依賴于instance name進行管理,同時必須都選擇default-instance.xml配置
??這個時候去對應的日志目錄下面 logs/test_canal_db/test_canal_db.log 只會看到一臺成功啟動的日志。
然后這個時候可以去zookeeper中去看看對應存儲的一些元信息。
[zk: localhost:2181(CONNECTED) 6] get /otter/canal/destinations/test_canal_db/running {"active":true,"address":"10.29.18.29:11111","cid":1}可以看到,這個時候對應的是有一個是master
2. 集群原理的解釋
2.1 啟動的時候決定誰為master
canal在啟動的時候會往zookeeper當中搶占式的創建一個臨時節點 /otter/canal/destinations/{0}/running,搶占成功的就是主節點,失敗的就是從節點。
2.2 運行過程中的HA切換
??同時,canal server在啟動的時候會對這個節點進行監聽,一旦有變化,就會進行再次的搶占。所以就通過這個實現了server端的HA。
2.3 客戶端的HA切換
??如果只有server端實現了切換肯定是不夠的,客戶端也需要仍然能夠連到正確的server上。所以客戶端也是使用了zookeeper來進行服務發現的。client也監聽了zk當中對應節點的信息變化。
3. 實際中運用的一些經驗總結
3.1 如何讓運行起來的canal(HA模式)恢復到初始狀態。
??在實際的應用中,有一次,dba因為一些原因要對數據庫中的日志進行重做,會停止我們canal連接的數據庫,導致我們的canal需要進行stop操作,同時,恢復后的binlog日志也是新的格式。
這個時候的操作應該是:
停止canal的消費端—>
停止canal中的master—>
停止剛剛成為master的另一臺機器—>
清除zookeeper中的信息(主要是client的信息,因為這里記錄了binlog的位置)。
??在DBA將數據庫日志重做以后,給出新的binlog信息,這個時候將binlog的信息配置到具體的 instance.properties當中
3.2 canal 連接的數據庫是slave,無法獲取到master的binlog的情況
??在剛開始進行canal的上線配置的時候出現過一些問題。有一個問題的表現是,canal連接的庫是對應的server ip 是 10.29.211.78 ,但是mysql是一個集群,我們連的是讀庫,寫庫在 10.29.211.43上面,出現的問題一直無法獲取到binlog,最開始懷疑是canal配置有問題,但是多個destionations ,其他的就正常,所以懷疑可能是數據庫配置的一些問題。后來懷疑可能是主從配置的一些問題。
在canal連的數據庫上執行
show variables like ‘log_%’
mysql> mysql> show variables like 'log_%'\G *************************** 1. row *************************** ... *************************** 11. row *************************** Variable_name: log_slave_updates Value: OFF *************************** 26. row *************************** Variable_name: log_warnings Value: 0 26 rows in set (0.08 sec)mysql??這里可以看到對應的有一個參數叫 log_slave_updates 這個參數標識了從庫是否在同步完主庫的binlog信息后將該信息也寫入自己的binlog當中。
??默認情況下,slave庫在拿到master的binlog以后,會進行解析,將數據寫入當前的庫當中,但是對應的從master過來的binlog卻會被丟棄,所以,讀庫雖然有主庫master寫入的數據,卻不回有主庫對應的binlog,所以canal也就拿不到對應的binlog。
解決方案:
將mysql 從庫設置log_slave_updates=true
3.3 canal版本預警
這個坑踩的有點虧,當時canal已經到了v1.0.26,所以我們就選用了v1.0.25 ,結果過了幾個月后,這個版本被官方標識為不建議生產使用,因為它爆出了太多bug,所以權當預警吧。
4 對應的canal的配置
這里將實際使用的配置貼出來,不一定是最好的,權作參考罷
vim canal.properties
這里只解釋一下HA模式的特別配置,canal.zkServers 和 canal.instance.global.spring.xml
配置了zookeeper相關的,在canal server啟動的時候會嘗試連接zookeeper,然后基于zookeeper中的數據來進行啟動。spring/default-instance.xml 則是對應的對metadata在zookeeper中的持久化的實現。
對應的數據庫的instance.properties配置
canal.instance.mysql.slaveId=2617201 canal.instance.master.address=10.29.15.227:3316 canal.instance.master.journal.name= canal.instance.master.position= canal.instance.master.timestamp= canal.instance.tsdb.enable=false canal.instance.dbUsername=canal_user canal.instance.dbPassword=hF5mgndM canal.instance.defaultDatabaseName=test canal.instance.connectionCharset=UTF-8 canal.instance.filter.regex=ll_social\\.post,ll_social\\.group,ll_social\\.tag,ll_social\\.social_user,ll_social\\.post_group,ll_social\\.group_special_post,ll_social\\.comment,ll_social\\.v_post,ll_social\\.v_feed_hot,ll_social\\.post_fav_count,ll_social\\.post_reply_count,ll_social\\.user_group,ll_social\\.group_influence canal.instance.filter.black.regex=5.canal的HA客戶端使用
代碼示例如下
String zookeeperHost = ConfigFace.getServerConfig().getString("zookeeper/host");CanalConnector connector = CanalConnectors.newClusterConnector(zookeeperHost,canalInstanceName, "", "");try {connector.connect();connector.subscribe("user_db.*");//Canal client端進行過濾// connector.subscribe();//Canal Server端進行過濾while (true) {Message message = connector.getWithoutAck(1000); // 獲取指定數量的數據long batchId = message.getId();int size = message.getEntries().size();if (batchId == -1 || size == 0) {Thread.sleep(1000);} else {action(message.getEntries());//進行自己的業務處理}connector.ack(batchId); // 提交確認// connector.rollback(batchId); // 處理失敗, 回滾數據}} catch (Exception e) {connector.rollback();log.error("從canal 中獲取數據出錯!", e);} finally {connector.disconnect();}可以看到HA的client也是通過zookeeper來獲取對應的server端的信息,并且會監聽zookeeper對應的節點信息,當running server 發生變化的時候會進行連接重建,所以可以實現HA。
參考:
http://blog.51cto.com/815632410/1420156
總結
以上是生活随笔為你收集整理的canal原理的一些学习-2(HA 模式搭建)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: canal原理的一些学习-1(canal
- 下一篇: kafka_consumer_消费原理介