Canal

Canal是阿里巴巴開源的一款數(shù)據(jù)庫同步組件,它通過分析MySQL數(shù)據(jù)庫的更新日志Binlog將更新的數(shù)據(jù)推送到不同的消費(fèi)方來達(dá)到數(shù)據(jù)同步的目的;

首先要了解,MySQL數(shù)據(jù)庫是一種日志優(yōu)先的數(shù)據(jù)庫,日志優(yōu)先意思是每次在更新數(shù)據(jù)時(shí)先將修改的數(shù)據(jù)信息寫入日志,然后才會(huì)進(jìn)行數(shù)據(jù)更新,這樣做的目的是保證高可用性,如果數(shù)據(jù)更新異常,可以通過日志來操作回滾或重試;MySQL日志以二進(jìn)制的方式存儲(chǔ),因此簡稱為BinLog(BinaryLog);

當(dāng)MySQL數(shù)據(jù)庫存在主從庫時(shí),主庫會(huì)將BinLog發(fā)送到從庫稱為RelayLog,從庫會(huì)根據(jù)RelayLog對(duì)從庫數(shù)據(jù)進(jìn)行同樣的修改,從而達(dá)到主從數(shù)據(jù)一致的目的;

MySQL的日志格式有三種:行模式、命令模式、混合模式;

行模式:日志中會(huì)記錄每一行數(shù)據(jù)被修改的形式,然后在slave端再對(duì)相同的數(shù)據(jù)進(jìn)行修改

優(yōu)點(diǎn):在行模式下,binlog可以不記錄執(zhí)行的sql語句信息,僅僅記錄每一行數(shù)據(jù)修改之前的值和修改之后的值,binlog會(huì)非常清楚的記錄下每一行數(shù)據(jù)修改的細(xì)節(jié)。不會(huì)出現(xiàn)語句模式中主從不一致的問題

缺點(diǎn):所有的執(zhí)行的語句當(dāng)記錄到日志中的時(shí)候,都將以每行記錄的修改來記錄,會(huì)產(chǎn)生大量的日志內(nèi)容

Statement Level 語句模式(默認(rèn)):每一條會(huì)修改數(shù)據(jù)的sql都會(huì)記錄到master的bin-log中。slave在復(fù)制的時(shí)候sql進(jìn)程會(huì)解析成和原來master端執(zhí)行過的相同的sql來再次執(zhí)行

優(yōu)點(diǎn):首先就是解決了行模式的下的缺點(diǎn),不需要記錄每一行數(shù)據(jù)的變化,減少binlog日志量,節(jié)約IO,提高性能

缺點(diǎn):由于只記錄語句,所以在語句模式下,已經(jīng)發(fā)現(xiàn)了有不少情況下會(huì)造成主從不一致的問題,例如使用系統(tǒng)函數(shù)UUID(),用戶自定義方法,存儲(chǔ)過程,觸發(fā)器等

Mixed 混合模式:MySQL會(huì)根據(jù)執(zhí)行的每一條具體的sql語句來區(qū)分對(duì)待記錄的日志格式,也就是在Statement和Row之間選擇一種

Canal的實(shí)現(xiàn)原理很簡單,CanalServer通過模擬slave從庫向主庫發(fā)送dump請(qǐng)求,主庫接收到dump請(qǐng)求后會(huì)向其發(fā)送BinLog,Canal對(duì)接收到的字節(jié)流形式的binlog進(jìn)行解析;

image.png

Canal的架構(gòu):


image.png

server代表一個(gè)canal運(yùn)行實(shí)例,對(duì)應(yīng)于一個(gè)jvm

instance對(duì)應(yīng)于一個(gè)數(shù)據(jù)隊(duì)列 (1個(gè)server對(duì)應(yīng)1..n個(gè)instance),負(fù)責(zé)模擬不同的DB-Slave,一個(gè)instance對(duì)應(yīng)一個(gè)DB,因此server與instance為一對(duì)多的關(guān)系,當(dāng)監(jiān)聽多個(gè)DB的數(shù)據(jù)變化就會(huì)有多個(gè)instance;

eventParser 數(shù)據(jù)源接入,模擬slave協(xié)議和master進(jìn)行交互,協(xié)議解析

eventSink Parser和Store鏈接器,進(jìn)行數(shù)據(jù)過濾,加工,分發(fā)的工作

eventStore 數(shù)據(jù)存儲(chǔ)

metaManager 增量訂閱&消費(fèi)信息管理器

在Canal架構(gòu)中要重點(diǎn)介紹一下Event的存儲(chǔ),目前只實(shí)現(xiàn)了內(nèi)存模式,即Event存放在內(nèi)存中;

其存儲(chǔ)結(jié)構(gòu)為RingBuffer:


image.png
image.png

Put: Sink模塊進(jìn)行數(shù)據(jù)存儲(chǔ)的最后一次寫入位置

Get: 數(shù)據(jù)訂閱獲取的最后一次提取位置

Ack: 數(shù)據(jù)消費(fèi)成功的最后一次消費(fèi)位置

Event的存儲(chǔ)數(shù)量是有限制的,當(dāng)RingBuffer存放不下新的Event時(shí)會(huì)通知Master延遲發(fā)送binlog;

Canal的高可用性時(shí)通過Zookeeper來保證的:

為了減少對(duì)mysql dump的請(qǐng)求,不同server上的instance要求同一時(shí)間只能有一個(gè)處于running,其他的處于standby狀態(tài);

Canal原生支持HA機(jī)制下啟動(dòng),只需配置相關(guān)的配置,無需額外的工作量;

Canal Server HA機(jī)制啟動(dòng)流程(如圖所示)


image.png

第一步當(dāng)不同sever上的監(jiān)聽相同DB的instance嘗試啟動(dòng)時(shí),需要去Zookeeper上注冊(cè)節(jié)點(diǎn),如果發(fā)現(xiàn)沒有活躍節(jié)點(diǎn),則進(jìn)行啟動(dòng),否則進(jìn)入StandBy狀態(tài),當(dāng)正在運(yùn)行的instance出現(xiàn)故障時(shí),比如ServerA 掛掉了,這時(shí)Zookeeper檢測到ServerA上的instance已經(jīng)不可用,通知ServerB上相應(yīng)的instance進(jìn)行啟動(dòng);

通過上面我們已經(jīng)了解了CanalServer的具體實(shí)現(xiàn)原理,CanalSever只是實(shí)現(xiàn)了對(duì)數(shù)據(jù)庫信息更新的感知,需要有相應(yīng)的消費(fèi)者來消費(fèi)這些消息來達(dá)到各自的業(yè)務(wù)目標(biāo),Otter同樣是阿里巴巴開源的一款工具,它可以對(duì)數(shù)據(jù)庫變更的信息進(jìn)行統(tǒng)一消費(fèi)并按照不同的方式推送到各個(gè)消費(fèi)方,而使用者只需在Otter平臺(tái)上配置相應(yīng)的規(guī)則即可實(shí)現(xiàn);


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容