Canal 源碼走讀

前言

canal 是什么? 引用一下官方回答:

阿里巴巴mysql數(shù)據(jù)庫binlog的增量訂閱&消費(fèi)組件

canal 能做什么赠橙?

基于日志增量訂閱&消費(fèi)支持的業(yè)務(wù):

  1. 數(shù)據(jù)庫鏡像
  2. 數(shù)據(jù)庫實(shí)時(shí)備份
  3. 多級(jí)索引 (賣家和買家各自分庫索引)
  4. search build
  5. 業(yè)務(wù)cache刷新
  6. 價(jià)格變化等重要業(yè)務(wù)消息

比如 LZ 目前就使用 canal 實(shí)現(xiàn)數(shù)據(jù)實(shí)時(shí)復(fù)制麸拄,搜索引擎數(shù)據(jù)構(gòu)建等功能实柠。既然要使用橱脸,就好好的研究一下抒和。

時(shí)間有限膳沽,一起來簡(jiǎn)單看看汗菜。

軟件架構(gòu)

關(guān)于 canal 的工作原理,我就不展開了挑社,有興趣的可以看看官方文檔陨界,或者這個(gè) ppt : https://docs.google.com/presentation/d/1MkszUPYRDkfVPz9IqOT1LLT5d9tuwde_WC8GZvjaDRg/edit#slide=id.p16

說白了, canal 就是偽裝成 mysql 的 slave痛阻,dump binlog菌瘪,解析 binlog,然后傳遞給應(yīng)用程序,總體還是蠻簡(jiǎn)單的俏扩。

好糜工,我們來看看 canal 的代碼架構(gòu)。

image.png

我們看到录淡,canal server 內(nèi)部由幾個(gè)模塊組成捌木, 最外部的是 Server,該 Server 接收 Canal Client 請(qǐng)求嫉戚,并返回 Client 數(shù)據(jù)刨裆。一個(gè) Server 就是一個(gè) JVM。每個(gè) Server 內(nèi)部由多個(gè) CanalInstance彬檀,每個(gè) CanalInstance 其實(shí)就是我們?cè)O(shè)置的 destination帆啃,通常是一個(gè)數(shù)據(jù)庫。

每個(gè) CanalInstance 內(nèi)部由 5 個(gè)模塊凤覆,分別是 parser 解析链瓦,sink 過濾,store 存儲(chǔ)盯桦,metaManager 元數(shù)據(jù)管理慈俯,Alarm 報(bào)警。

這 5 個(gè)模塊是干嘛的呢拥峦?

簡(jiǎn)單說一下:

當(dāng) Canal Server 啟動(dòng)后贴膘,會(huì)根據(jù)配置啟動(dòng) N 個(gè) CanalInstance, 每個(gè) CanalInstance 都會(huì)使用 socket 連接 mysql略号,dump binlog刑峡,然后將數(shù)據(jù)交給 parser 解析,sink 過濾玄柠,store 存儲(chǔ)突梦,當(dāng) client 連接時(shí),會(huì)從 zk 上讀取該 client 的信息羽利,而 metaManager 元數(shù)據(jù)管理就是管理 zk(當(dāng)然有多種實(shí)現(xiàn)宫患,比如存儲(chǔ)在文件中) 信息的,如果發(fā)生錯(cuò)誤了这弧,就調(diào)用 Alarm 發(fā)送報(bào)警信息(你可以接入自己公司的監(jiān)控系統(tǒng))娃闲,目前是打印日志。

Canal 啟動(dòng)流程

canal 代碼量目前有 6 萬多行匾浪,去除 2 個(gè) ProtocolBuffer 生成類大概 1.7 萬行皇帮,也還有 4.3 萬行,代碼還是不少的蛋辈。

啟動(dòng)過程也比較繞属拾。這里我簡(jiǎn)單畫了一個(gè)流程圖:

解釋一下這個(gè)圖:

canal 腳本從 CanalLauncher main 方法啟動(dòng),然后調(diào)用 CanalController 的 start 方法,CanalController 調(diào)用 InstanceConfigMonitor 的 start 方法捌年,最后調(diào)用 canal 關(guān)鍵組件 CanalServerWithEmbedded 的 start 方法瓢娜。

在 Canal 內(nèi)部, 有 CanalServerWithEmbedded 和 CanalServerWithNetty礼预,前者是沒有 Server 端口的眠砾,是一個(gè)無端口的代理。后者是基于 Netty 實(shí)現(xiàn)的服務(wù)器托酸,在 channelRead 方法中褒颈,會(huì)調(diào)用 CanalServerWithEmbedded 的相關(guān)方法。

CanalServerWithEmbedded 是單例的励堡, 內(nèi)部會(huì)有多個(gè) CanalInstance谷丸, 他有多個(gè)實(shí)現(xiàn),獨(dú)立版本中使用的是 CanalInstanceWithSpring 版本应结,基于 Spring 管理組件的生命周期刨疼。

每個(gè) CanalInstance 內(nèi)部有 5 個(gè)組件,也就是上面說的幾個(gè)組件鹅龄,他們會(huì)分別啟動(dòng)揩慕。

其中,比較關(guān)鍵的是 parser扮休,sink迎卤,store。

CanalEventParser 啟動(dòng)后玷坠,會(huì)啟動(dòng)一個(gè)叫做 parseThread 線程蜗搔,不停的循環(huán)。主要是:構(gòu)造與 mysql 的連接八堡,然后啟動(dòng)心跳線程樟凄,然后開始 dump binlog。

dump 出來的 binlog 通過 disruptor 無鎖隊(duì)列發(fā)布兄渺,內(nèi)部由 3 個(gè)消費(fèi)者按照順序消費(fèi) binlog不同,處理完之后,交給了 sink 模塊溶耘。

然后是 sink,這個(gè)比較簡(jiǎn)單服鹅,就不說了凳兵。sink 處理完之后,交給了 store 模塊企软。

store 模式是一個(gè)類似 RingBuffer 的循環(huán)數(shù)組庐扫,存儲(chǔ)著從 mysql dump 出來的數(shù)據(jù),client 也是從這里獲取數(shù)據(jù)的。該數(shù)組維護(hù)著 3 個(gè)指針形庭,get铅辞,put, ack萨醒。

這里比較奇怪的是斟珊,為什么不使用責(zé)任鏈模式夠組裝組件?

Canal 數(shù)據(jù)流向

看了啟動(dòng)流程富纸,再來看看 canal 內(nèi)部運(yùn)行的數(shù)據(jù)流向是什么樣子的囤踩。我這里簡(jiǎn)單畫了一個(gè)圖。

獨(dú)立版本的 Canal 使用 Netty 暴露端口晓褪,使用自己構(gòu)造的 SessionHandler 處理 TCP 請(qǐng)求堵漱,SessionHandler 將請(qǐng)求交給 CanalServerWithEmbedded 來處理。

我們看 CanalServerWithEmbedded 的一些方法涣仿,例如 subscribe勤庐,get,ack 等好港,都是和 client 對(duì)應(yīng)的方法愉镰,也就是說,CanalServerWithEmbedded 是和 client 打交道的一個(gè)類媚狰。

CanalServerWithEmbedded 內(nèi)部管理所有的 CanalInstance岛杀,通過 Client 的信息,找到 Client 訂閱的 CanalInstance崭孤,然后調(diào)用 CanalInstance 內(nèi)部的 Store 模塊类嗤,也就是那個(gè) RingBuffer 的 get 方法,獲取 RingBuffer 的數(shù)據(jù)辨宠。

從 Myslq 的角度看遗锣,MysqlConnection 從 Myslq dump 數(shù)據(jù),交給 parser 解析嗤形,parser 解析完精偿,交給 sink,sink 處理完赋兵,交給 store 保存笔咽,等待 client 前來獲取。

看完了數(shù)據(jù)流向霹期,如果對(duì)哪里有什么疑問叶组,就可以看看哪個(gè)模塊對(duì)應(yīng)的代碼是什么,直接看是看就好了历造。

總結(jié)

花了點(diǎn)時(shí)間看了看 Canal 的代碼甩十,總體上還是非常好的船庇,只是有些地方有點(diǎn)疑問,例如 parser侣监,sink鸭轮,store 為什么不使用過濾器模式。

Client 和 CanalServerWithEmbedded 為什么不使用 RPC 的方式交互橄霉,這樣更簡(jiǎn)單明了窃爷。

代碼里回調(diào)方法太多太長(zhǎng),影響閱讀酪劫。

但總體瑕不掩瑜吞鸭,值得一讀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末覆糟,一起剝皮案震驚了整個(gè)濱河市刻剥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌滩字,老刑警劉巖造虏,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異麦箍,居然都是意外死亡漓藕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門挟裂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來享钞,“玉大人,你說我怎么就攤上這事诀蓉±跏” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵渠啤,是天一觀的道長(zhǎng)狐肢。 經(jīng)常有香客問我,道長(zhǎng)沥曹,這世上最難降的妖魔是什么份名? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮妓美,結(jié)果婚禮上僵腺,老公的妹妹穿的比我還像新娘。我一直安慰自己壶栋,他們只是感情好想邦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著委刘,像睡著了一般丧没。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上锡移,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天呕童,我揣著相機(jī)與錄音,去河邊找鬼淆珊。 笑死夺饲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的施符。 我是一名探鬼主播往声,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼戳吝!你這毒婦竟也來了浩销?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤听哭,失蹤者是張志新(化名)和其女友劉穎慢洋,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體陆盘,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡普筹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了隘马。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片太防。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖酸员,靈堂內(nèi)的尸體忽然破棺而出蜒车,到底是詐尸還是另有隱情,我是刑警寧澤沸呐,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布醇王,位于F島的核電站,受9級(jí)特大地震影響崭添,放射性物質(zhì)發(fā)生泄漏寓娩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一呼渣、第九天 我趴在偏房一處隱蔽的房頂上張望棘伴。 院中可真熱鬧,春花似錦屁置、人聲如沸焊夸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽阱穗。三九已至饭冬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間揪阶,已是汗流浹背昌抠。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鲁僚,地道東北人炊苫。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像冰沙,于是被迫代替她去往敵國(guó)和親侨艾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容