Canal集群部署遇到的一些問題
最近一周在部署canal的HA集群版(v1.1.5),把遇到的問題和一些體會(huì)總結(jié)下,這篇文章不會(huì)以宏觀的概念去理解canal的原理和設(shè)計(jì)理念,但通過實(shí)踐,確實(shí)對(duì)canal的運(yùn)維和設(shè)計(jì)有了更深刻的印象,而且如果你習(xí)慣于原來的單機(jī)部署模式,那么在部署集群版的時(shí)候,可能會(huì)覺得不適應(yīng)。
那么部署HA集群版的原因是什么呢?首先如果按照傳統(tǒng)的模式,增加一個(gè)instance需要手動(dòng)拷貝一份配置,修改配置,然后重啟服務(wù),可操作性和可理解性非常差,而集群版有了UI控制臺(tái),非常的簡(jiǎn)單;其次canal service可以做到橫向擴(kuò)容,可用性上好了很多,當(dāng)然canal admin本身還是一個(gè)單點(diǎn)。
canal從應(yīng)用上主要包含三個(gè)概念,canal-service(canal.properties),canal-instance(canal.properties),canal-admin,前兩者是一對(duì)多的概念,且是一個(gè)整體,比如一個(gè)service上可以部署多個(gè)instance;而canal-admin用于管理canal-service。
理解了這三者概念,那么首先配置的就是canal-admin,當(dāng)然我不會(huì)貼一張圖,官網(wǎng)上都有。
初始化數(shù)據(jù)庫(kù),為了管理service和instance,需要一個(gè)mysql數(shù)據(jù)庫(kù)。
conf/application.yml中配置的adminUser和adminPasswd非常重要,首先它用于登錄admin后臺(tái),但一旦修改后,這個(gè)配置對(duì)于admin后臺(tái)登錄就沒有用了。
它重要的原因在于canal admin和canal service通信校驗(yàn)會(huì)用到,這后面會(huì)說。
接下去就是啟動(dòng)canal-admin,如果成功就在8089端口啟動(dòng)UI服務(wù),強(qiáng)烈建議查看logs/admin.log日志,以便用于排查問題。
對(duì)于admin來說,有兩個(gè)配置非常重要,就是config目錄下的canal-template.properties,instance-template.properties,它們稱為模板,也就是說service和instance服務(wù)本地配置文件都沒有用了,它們都會(huì)讀取admin的配置,這樣說明service服務(wù)會(huì)非常的輕量。
其次我們啟動(dòng)canal-server服務(wù)。在運(yùn)行的時(shí)候,首先要有一個(gè)基本配置文件。
官方讓canal_local.properties覆蓋canal.properties,進(jìn)一步說明canal.properties的配置在集群版完全無用,這個(gè)local表明這是為了運(yùn)行本地基礎(chǔ)服務(wù),建立和admin的通訊。
sh bin/startup.sh local或sh bin/startup.sh都可以啟動(dòng)。也強(qiáng)烈建議查看logs/canal/canal.log文件用于排查問題。
然后看看基礎(chǔ)配置包含什么:
- # register ip
- canal.register.ip =
- # canal admin config
- canal.admin.manager = 127.0.0.1:8089
- canal.admin.port = 11110
- canal.admin.user = admin
- canal.admin.passwd = 4ACFE3202A5FF5CF467898FC58AAB1D615029441
- # admin auto register
- canal.admin.register.auto = true
- canal.admin.register.cluster =
canal.register.ip就是service的本地IP,canal.admin.manager是admin的遠(yuǎn)端地址,在啟動(dòng)的時(shí)候用于連接admin。
canal.admin.passwd密碼非常重要,它會(huì)和admin做雙向認(rèn)證,canal-server會(huì)以這個(gè)密文和canal-admin做請(qǐng)求,同時(shí)canal-admin也會(huì)以密碼原文生成加密串后和canal-server進(jìn)行admin端口鏈接,所以這里一定要確保這兩個(gè)密碼內(nèi)容的一致性。
canal.admin.port是service用于和admin建立通訊的端口。
canal.admin.register.cluster我沒去試驗(yàn),就是service啟動(dòng)的時(shí)候會(huì)自動(dòng)加入admin配置的集群中(可以多個(gè)集群)。
啟動(dòng)的時(shí)候我遇到一個(gè)問題,提示Caused by: com.alibaba.otter.canal.common.CanalException: requestGet for canal config error: canal.properties config is empty錯(cuò)誤。原因就在于service啟動(dòng)的時(shí)候會(huì)先admin拉取canal-template.properties配置。而我在admin啟動(dòng)后并沒有立刻配置canal-template.properties(困惑的是canal-template.properties這個(gè)配置動(dòng)作屬主是配置集群,所以比較有疑惑性,但看到canal.admin.register.cluster,我覺得對(duì)于每一臺(tái)service來說,它在設(shè)計(jì)中默認(rèn)是只能配置為一個(gè)集群,從這個(gè)集群配置中拉取canal-template.properties,這樣理解就比較合理了)
接下去說說如何在admin上管理集群、service、instance。
首先要建立集群,集群是通過zookeeper維護(hù)狀態(tài)的,那存儲(chǔ)什么了呢?個(gè)人覺得service連接admin的時(shí)候,會(huì)把存儲(chǔ)狀態(tài)放到zookeeper,admin通過zookeeper獲取sercie的節(jié)點(diǎn)信息,當(dāng)然可能還會(huì)存儲(chǔ)其他的。
接下去配置service和instance,都是隸屬關(guān)系。這里面重點(diǎn)說下自己的理解。
設(shè)想是建立二個(gè)集群,一個(gè)是qa集群,一個(gè)是online集群,但它們共用一群service,實(shí)際上在建立service的時(shí)候,如果發(fā)現(xiàn)節(jié)點(diǎn)(ip和port)已經(jīng)使用過,就不允許建立了,聯(lián)想下上面提到的canal.admin.register.cluster,進(jìn)一步釋然了。
這說明對(duì)于一個(gè)service節(jié)點(diǎn)來說,它只能連接一個(gè)集群,在這種情況下,如果為了區(qū)分qa集群和online集群,那么就要配置不同的service節(jié)點(diǎn)(ip和port不同就可以)。
也做了一些測(cè)試驗(yàn)證漂移,比如把某個(gè)service關(guān)閉,那么instance上的所屬主機(jī)就會(huì)漂移。
最后說說service和instance配置,這里主要說基本的信息。
- # tcp bind ip
- canal.ip =
- # register ip to zookeeper
- canal.register.ip =
- canal.port = 11111
- canal.metrics.pull.port = 11112
- canal.zkServers = xwj-zookeeper-1.com:2181,xwj-zookeeper-2.com:2181,xwj-zookeeper-3.com:2181
- canal.serverMode = kafka
- canal.instance.global.spring.xml = classpath:spring/default-instance.xml
- kafka.bootstrap.servers = xwj-kafka-1.com:9092,xwj-kafka-2.com:9092,xwj-kafka-3.com:9092
- kafka.acks = all
現(xiàn)在看上去非常清晰,canal.port是本地服務(wù)的端口,canal.metrics.pull.port可以接入監(jiān)控系統(tǒng),使用kafka作為隊(duì)列,default-instance.xml可以將pos信息同步到zookeeper,對(duì)于集群版我覺得只能配置它(沒有測(cè)試),原因一臺(tái)service掛了,接管的service必須知道消費(fèi)到哪兒了。
- canal.instance.master.address=
- canal.instance.dbUsername=dts
- canal.instance.dbPassword=!xi5jie@com#
- canal.instance.connectionCharset = UTF-8
- canal.instance.filter.regex=.*\\..*
- canal.mq.partitionsNum=3
- canal.mq.partitionHash=test.table:id^name,.*\\..*
這個(gè)就更簡(jiǎn)單了,配置從那個(gè)數(shù)據(jù)庫(kù)那個(gè)表監(jiān)測(cè)binlog,然后同步到那個(gè)kafka topic中。
























