canal源碼分析

本人閱讀canal源碼心得mysql

      canal用來幹嗎的?sql

      說的簡單直白點就把你的數據庫的binlog文件內容準實時傳遞給你的客戶端,有了數據還不是想幹嗎就幹嗎。數據庫

      它的大體框架是什麼呢?數組

      若是leader提出設計canal這樣的需求,腦海中確定浮現這樣一個類CS的系統架構,其中S端就用來處理一些跟mysql,binlog以及其餘一些雜七雜八的事,C端最多把接收的數據封裝下,作下簡單處理。至於怎麼通訊呢?那確定首選Netty了。有個大體框架,接來下就是進一步細化。session

     客戶端、服務端的的信息管理數據結構

     既然有客戶端和服務端,那確定要管理下這些元信息,信息管理無非就是把信息找個地方存儲下,在目前框架中常見的就這幾種:本地內存存儲,本地文件存儲,其餘第三方存儲容器。在canal裏面採用本地內存+zookeeper存儲方式。zookeeper中建立了以下幾個節點(針對服務端):架構

     1; /otter/canal/cluster.其中cluster的child節點分別存儲的是各個S端的server信息,節點名稱ip:port,屬性:臨時節點,框架

    2;/otter/canal/destinations/{destination}/cluster/{ip:port}   註冊實例信息fetch

    3;/otter/canal/destinations/{destiantion}/running/  存儲的是正在運行的節點信息編碼

    既然有了這些節點那確定要在在節點上設置監聽器,監聽器主要是處理節點丟失和節點信息有變的狀況。對於註冊實例信息的節點,監聽器主要是在session斷連的狀況下從新註冊信息。對於running節點信息,監聽器主要處理節點內容改變和節點刪除,節點內容有變(例如主動下線某個實例)時,則Server端發起stop non-active 的實例操做,若節點刪除了,則主動啓動實例,並註冊信息到running節點。

    如何取出binlog的記錄並存儲

    客戶端和服務端的metadata信息處理完了,接下來處理的是如何把binlog的信息fetch出來,存儲在本地。canal對此抽象出了三個組件:EventParser,EventSink,EventStore和MetaManager。其中MetaManager記錄的是客戶端的消費信息,主要爲三種:destinations——Map數據結構,key爲server端實例名稱,value爲訂閱了該實例的消費客戶端;cursors——Map數據結構,key爲客戶端的抽象類ClientIdentity,value爲消費的位置信息;batches——記錄消費的批次信息。MetaManager裏面的信息會同步到Zookeeper中(針對ZookeeperMetaManager),其中zookeeper的對應的存儲節點分別爲:

     1,destiantions:/otter/canal/destinations/{destination}

     2,cursor:/otter/canal/destiantions/{destination}/cursor/{clientId}

     3,batches:/otter/canal/destiantions/{destination}/mark/{clientId}/{batchId},

一份信息兩個地方存儲,爲了保證數據的一致性,啓動了一個線程,定時更新本地內存的cursor信息到遠程zookeeper中。

    EventSink相似於過濾器的做用,針對獲取到的Bin log進行過濾。EventSink主要包含Handers(List數據結構),一些固定的過濾性配置:filterTransactionEntry(是否須要過濾事務頭和尾部),filterEmptyTransactionEntry(是否須要過濾空事務頭和尾部),一個過濾器filter。EventSink裏面的組件功從組件的名字就能看出來了。

其中EventStore用於存儲Bin log的記錄,主要數據結構是數組和相關的位置index屬性,經過一個數組和index屬性(最新put的位置在哪,消費到哪了),構建了一個環形的隊列。

其中EventParser主要兩個功能,一個是按需fetch bin log記錄,一個是解析bin log記錄轉化成CanalEntry。其中Bin log的位置獲取,主要是經過查詢 show master status 和show binlog events limit 1,支持查找最新的和查找某個時刻後的。固然在這個過程當中還須要考慮種種異常狀況,好比文件找不到怎麼辦,發生了準備切換怎麼辦(回退到fallbackIntervalInSeconds以前,按時間來fetch)。

   EventParser,EventStore,EventSink之間如何協調工做?

   以下面時序圖所示(來源:https://www.jianshu.com/p/b50cbb7254b8):

 

  如何接受客戶端的請求

   S端的架構設計好了,接下來設計C端與S端的通訊。Canal中的鏈接部分是基於Netty,經過在ChannelPipeline中添加FixedHeaderFrameDecoder,HandshakeInitializationHandler,ClientAuthenticationHandler,SessionHandler,從名稱看也能猜出FixedHeaderFrameDecoder用於編碼解碼,HandshakeInitializationHandler用於處理請求鏈接的動做,ClientAuthenticationHandler那確定是校驗客戶端了,核心的處理內容在SessionHandler。其中SessionHandler主要處理客戶端的5中指令:SUBSCRIPTION,UNSUBSCRIPTION,GET,CLIENTACK,CLIENTROLLBACK。針對SUBSCRIPTION請求,Server記錄客戶端要訂閱實例信息,以及客戶端的過濾器信息。針對GET請求,Server從EventStore中獲取Bin log記錄信息,針對ACK請求, Server更新客戶端的消費記錄,針對CLIENTROLLBACK請求 ,客戶端端消費失敗了,Server將該客戶端的消費進度回滾。

   客戶端

  客戶端設計時要解決得首要問題就是採用什麼方式來消費Bin log記錄。客戶端採用的時候pull的方式,定時去拉取信息。

  系統框架圖

相關文章
相關標籤/搜索