一文詳解 Canal Instance 設計理念與定製開發思路


從 Canal 系列的第一篇文章我們基本能瞭解到,Instance 是 Canal 數據同步的核心,在一個 Canal 實例中只有啓動 Instace,才能實現數據的同步,那 Instance 到底是“何許人也”,本文將以源碼爲手段,試圖揭開 Instance 的神祕面紗。

1、Canal Instance 類繼承體系

在這裏插入圖片描述
重要的類說明如下:

  • CanalInstanceCanal Instance 接口,即定義 Instance 的基本特徵,主要定義如下方法:

    • String getDestination()
      實例的目的地名稱,在 Canal 中表示一個源實例名稱,對應一個 MySQL 實例信息,例如 192.168.1.3:3306,這裏爲該實例取一個名稱。
    • CanalEventParser getEventParser()
      事件解析器,即 Binlog 解析器,負責解析 binlog 日誌。
    • CanalEventSink getEventSink()
      EventParse 與 EventStore 的連接器,主要處理數據的過濾、加工與分發,即提供了對 binlog 原始數據進行“加工”的切入點,EventStore 存儲的就是經 EventSink處理過的數據。
    • CanalEventStore getEventStore()
      事件存儲器,即 Canal Instance 作爲 MySQL 的 “Slave” 服務器,需要將同步過來的數據進行存儲,然後被 Canal 的客戶端最終會從 EventStore 中獲取數據,目前 Canal 只實現了基於內存的 EventStore,那 Canal 是如何避免內存泄露,並且如何避免數據丟失的,這將是後續我們需要研究的重點。
    • CanalMetaManager getMetaManager()
      Canal 元數據管理器,例如記錄 消費端消費進度,即從 Canal EventStore 中處理數據的情況。
    • CanalAlarmHandler getAlarmHandler()
      告警服務。
  • AbstractCanalInstance
    CanalInstance的抽象實現類。

  • CanalInstanceWithManager
    基於手動編程式的 CanaInstance,主要通過API的方式手動生成 CanalInstance 實例。 可以類比 Spring 基於編程API 的事務管理器。

  • CanalInstanceWithSpring
    基於 Spring 方式構建 CanaInstance。

  • CanalInstanceGenerator
    Canal Instance 的構造類體系,即通過該類提供的方法創建 CanalInstance 實例,提供基於 Spring、手動管理等方式。

2、CanalInstance 四大核心組件

從類層次瞭解 Canal Instance 顯得不那麼直觀,接下來先拋出一個使用場景,再結合架構圖進一步加深對 Canal Instance 的理解。

例如某公司的訂單系統使用了分庫分表,數據庫的分別部署在 192.168.1.166:3306,192.168.1.168:3306 兩個數據庫,並且每一個數據庫上會創建多個 schema,例如 order_db、user_db,那現在爲了對訂單提供多維度的查詢,統計等功能,架構組因此提出通過訂閱數據庫 binlog 日誌,將兩個訂單庫中的訂單數據,即將 order_db 中的數據同步到 elasticsearch,而 Canal 的設計初衷就是爲了解決上述問題,故我們可以邊思考這個場景,來反推一下 Canal Instance 的設計理念。

Canal Instance 的架構圖如下圖所示:
在這裏插入圖片描述
Canal 中數據的同步是由 CanalInstance 組件負責,一個 Canal Server 實例中可以創建多個 CanalInstance 實例。

每一個 CanalInstance 可以看成是對應一個 MySQL 實例,即案例中需要同步兩個數據庫實例,故最終需要創建兩個 CanalInstance。其實也不難理解,因爲 MySQL 的 binlog 就是以實例爲維度進行存儲的。Canal Instance 包含了 4個 核心組件 :EventParse、EventSink、EventStore、CanaMetaManager,在這裏主要是闡明其作用,後續文章會一一詳細介紹,以便更好的指導實踐。

  • EventParse 組件
    負責解析 binlog日誌,其職責就是根據 binlog 的存儲格式將有效數據提取出來,這個不難理解,我們也可以通過該模塊,進一步瞭解一下 binglog 的存儲格式。
  • EventSink 組件
    結合數據同步案例,在一個數據庫實例上通常會創建多個 Schema,但通常並不是所有的 schema 都需要被同步,如果直接將 EventParse 解析出來的數據全部傳入EventStore 組件,將對 EventStore 帶來不必要的性能消耗;另外本例中使用了分庫分表,需要將多個庫的數據同步到單一源,可能需要涉及到合併、歸併等策略。以上等等等需求就是 EventSink 需要解決的問題域。
  • EventStore 組件
    用來存儲經 canal 轉換的數據,被 Canal Client 進行消費的數據,目前 Canal 只提供了基於內存的存儲實現。大家不妨先思考一下,採用基於內存的存儲模式,如何避免內存溢出,其具體實現將在後續文章中詳細剖析。
  • CanalMetaManager 組件
    元數據存儲管理器。在 Canal 中最基本的元數據至少應該包含 EventParse 組件解析的位點與消費端的消費位點。Canal Server 重啓後要能從上一次未同步位置開始同步,否則會丟失數據。在將數據庫數據同步到 es 的示例中,所謂的 canal 客戶端就是從 Canal Server 即 EventStore 中獲取數據,並將數據寫入 es 中,並上報寫入進度,這些信息都是由 CanalMetaManager 組件完成。

從最新的版本來看,Canal 支持直接將解析後的數據發送到MQ,故 CanalInstance 中還持有另外一個組件:CanalMQConfig,關於 MQ 的一些配置,提供了多種策略實現 shcema、table 到 MQ Topic 的自動映射管理,爲 Canal 的使用者帶來更多便利,這部分內容會在後續文章中單獨介紹,這裏先暫時不過多討論。

經過上面的瞭解,我想大家對 Canal Instance 有了一個相對全面的瞭解了吧,接下來我們再來關注一下 CanalInstance 的構造方式,這個對後續的實踐有着非常重要的影響。

3、CanalInstance 構造方式

Canal 中提供了兩種方式對 Instance 進行初始化:Spring 與 手動編程方式。 CanalInstance 最最核心的就是上述提到的4個組件,即 CanalInstanceWithManager 類的具體職責就是管理上述核心組件,即提供對上述組件的加載、啓動、停止,並協調,從其名字就能看出來,從其構造函數同樣能得知:
在這裏插入圖片描述
編程方式創建 Canal Instance 就變得簡單起來,只需設置參數,並創建 CanalInstanceWithManger 方法即可,正如示例代碼中使用的那樣。
在這裏插入圖片描述
另外 Canal 提供了對 Spring 的整合,將 canal Instance 的相關核心組件納入 Spring 的管理,其實現類爲: CanalInstanceWithSpring,對應的 Spring 配置示例如下圖所示:

溫馨提示:基於 Canal 二次開發的編程技巧思考如下:Canal 框架本身將 Canal Server 做成了啓動腳本,可以通過自定義 Instance,即從 instance 配置文件中加載配置,然後啓動 Canal Server 解析 Binlog 日誌,最終按照預定的配置進行工作,例如在生產環境搭建一些 Canal 集羣,統一交由運維去手動維護,如果需要數據同步,則配置相應的 instance 文件,然後進行啓動就生效,其實這種模式處於 Canal 的初階階段,更好的方式是對 Canal 進行二次開發,通過可視化的界面,通過界面的方式定義數據同步任務,例如將指定數據庫實例上的指定 Schema 的 binglog 日誌同步到指定消息集羣的指定 topic,並且可重推、隨時停止,重啓,這樣 Canal 的維護者無需關注底層的細節,只需要通過頁面簡單配置一下即可。

本文就先介紹到這裏了,本文的目的是瞭解 CanalInstance 在 Canal 中所處的定位,揭開其4大核心組件的作用與引入目的,爲接下來逐個學習研究打下基礎。

源碼研究 Canal 學習方法提示:目前 Canal 系列雖然在持續連載,目前筆者只能儘量做到周更,如果讀者朋友們也正在研究 Canal,我覺得大家在讀取本文後,可以繼續深入研究其四大核心組件,並帶着問題去研究,例如在學習元數據管理時是如何保證數據不丟失,重啓後又是如何定位位點的。如果大家想更全局的去研究 Canal,我覺得除了閱讀 Canal 官方的設計手冊,還可以專門去看一下 CanalParameter 這個類,Canal 支持的所有配置屬性,並且都有相應的註釋,關於 Canal 的所有一切,都可以從這裏窺探出端倪,然後可以選擇感興趣的內容加以繼續深入學習。


好了,本文就介紹到這裏了,您的點贊與轉發是對我持續輸出高質量文章最大的鼓勵。

歡迎加筆者微信號(dingwpmz),加羣探討,筆者優質專欄目錄:
1、源碼分析RocketMQ專欄(40篇+)
2、源碼分析Sentinel專欄(12篇+)
3、源碼分析Dubbo專欄(28篇+)
4、源碼分析Mybatis專欄
5、源碼分析Netty專欄(18篇+)
6、源碼分析JUC專欄
7、源碼分析Elasticjob專欄
8、Elasticsearch專欄(20篇+)
9、源碼分析MyCat專欄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章