Canal集群部署遇到的一些問題
最近一周在部署canal的HA集群版(v1.1.5),把遇到的問題和一些體會總結下,這篇文章不會以宏觀的概念去理解canal的原理和設計理念,但通過實踐,確實對canal的運維和設計有了更深刻的印象,而且如果你習慣于原來的單機部署模式,那么在部署集群版的時候,可能會覺得不適應。
那么部署HA集群版的原因是什么呢?首先如果按照傳統的模式,增加一個instance需要手動拷貝一份配置,修改配置,然后重啟服務,可操作性和可理解性非常差,而集群版有了UI控制臺,非常的簡單;其次canal service可以做到橫向擴容,可用性上好了很多,當然canal admin本身還是一個單點。
canal從應用上主要包含三個概念,canal-service(canal.properties),canal-instance(canal.properties),canal-admin,前兩者是一對多的概念,且是一個整體,比如一個service上可以部署多個instance;而canal-admin用于管理canal-service。
理解了這三者概念,那么首先配置的就是canal-admin,當然我不會貼一張圖,官網上都有。
初始化數據庫,為了管理service和instance,需要一個mysql數據庫。
conf/application.yml中配置的adminUser和adminPasswd非常重要,首先它用于登錄admin后臺,但一旦修改后,這個配置對于admin后臺登錄就沒有用了。
它重要的原因在于canal admin和canal service通信校驗會用到,這后面會說。
接下去就是啟動canal-admin,如果成功就在8089端口啟動UI服務,強烈建議查看logs/admin.log日志,以便用于排查問題。
對于admin來說,有兩個配置非常重要,就是config目錄下的canal-template.properties,instance-template.properties,它們稱為模板,也就是說service和instance服務本地配置文件都沒有用了,它們都會讀取admin的配置,這樣說明service服務會非常的輕量。
其次我們啟動canal-server服務。在運行的時候,首先要有一個基本配置文件。
官方讓canal_local.properties覆蓋canal.properties,進一步說明canal.properties的配置在集群版完全無用,這個local表明這是為了運行本地基礎服務,建立和admin的通訊。
sh bin/startup.sh local或sh bin/startup.sh都可以啟動。也強烈建議查看logs/canal/canal.log文件用于排查問題。
然后看看基礎配置包含什么:
- # 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的遠端地址,在啟動的時候用于連接admin。
canal.admin.passwd密碼非常重要,它會和admin做雙向認證,canal-server會以這個密文和canal-admin做請求,同時canal-admin也會以密碼原文生成加密串后和canal-server進行admin端口鏈接,所以這里一定要確保這兩個密碼內容的一致性。
canal.admin.port是service用于和admin建立通訊的端口。
canal.admin.register.cluster我沒去試驗,就是service啟動的時候會自動加入admin配置的集群中(可以多個集群)。
啟動的時候我遇到一個問題,提示Caused by: com.alibaba.otter.canal.common.CanalException: requestGet for canal config error: canal.properties config is empty錯誤。原因就在于service啟動的時候會先admin拉取canal-template.properties配置。而我在admin啟動后并沒有立刻配置canal-template.properties(困惑的是canal-template.properties這個配置動作屬主是配置集群,所以比較有疑惑性,但看到canal.admin.register.cluster,我覺得對于每一臺service來說,它在設計中默認是只能配置為一個集群,從這個集群配置中拉取canal-template.properties,這樣理解就比較合理了)
接下去說說如何在admin上管理集群、service、instance。
首先要建立集群,集群是通過zookeeper維護狀態的,那存儲什么了呢?個人覺得service連接admin的時候,會把存儲狀態放到zookeeper,admin通過zookeeper獲取sercie的節點信息,當然可能還會存儲其他的。
接下去配置service和instance,都是隸屬關系。這里面重點說下自己的理解。
設想是建立二個集群,一個是qa集群,一個是online集群,但它們共用一群service,實際上在建立service的時候,如果發現節點(ip和port)已經使用過,就不允許建立了,聯想下上面提到的canal.admin.register.cluster,進一步釋然了。
這說明對于一個service節點來說,它只能連接一個集群,在這種情況下,如果為了區分qa集群和online集群,那么就要配置不同的service節點(ip和port不同就可以)。
也做了一些測試驗證漂移,比如把某個service關閉,那么instance上的所屬主機就會漂移。
最后說說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
現在看上去非常清晰,canal.port是本地服務的端口,canal.metrics.pull.port可以接入監控系統,使用kafka作為隊列,default-instance.xml可以將pos信息同步到zookeeper,對于集群版我覺得只能配置它(沒有測試),原因一臺service掛了,接管的service必須知道消費到哪兒了。
- 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,.*\\..*
這個就更簡單了,配置從那個數據庫那個表監測binlog,然后同步到那個kafka topic中。