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

語言: CN / TW / HK

做積極的人,越努力越幸運!
一文詳解 Canal Instance 設計理念與定製開發思路
從 Canal 系列的第一篇文章我們基本能瞭解到,Instance 是 Canal 資料同步的核心,在一個 Canal 例項中只有啟動 Instace,才能實現資料的同步,那 Instance 到底是“何許人也”,本文將以原始碼為手段,試圖揭開 Instance 的神祕面紗。

1、Canal Instance 類繼承體系


一文詳解 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 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 設計理念與定製開發思路

程式設計方式建立 Canal Instance 比較簡單,只需設定引數,並建立 CanalInstanceWithManger 方法即可,正如示例程式碼中使用的那樣。
一文詳解 Canal Instance 設計理念與定製開發思路
另外 Canal 提供了對 Spring 的整合,將 canal Instance 的相關核心元件納入 Spring 的管理,其實現類為:CanalInstanceWithSpring,對應的 Spring 配置示例如下圖所示:
一文詳解 Canal Instance 設計理念與定製開發思路


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

原始碼 Canal 系列的第一篇文章後有好幾個粉絲表示目前也在研究 Canal,由於筆者目前只能儘量保持周更,如果大家希望加快研究 Canal 的步伐,筆者有如下建議:

1、深入研究其四大核心元件,並帶著問題去研究,例如在學習元資料管理時是如何保證資料不丟失,重啟後又是如何定位位點的。
2、如果大家想更全域性的去研究 Canal,我覺得除了閱讀 Canal 官方的設計手冊,還可以專門去看一下 CanalParameter 這個類,Canal 支援的所有配置屬性,並且都有相應的註釋,關於 Canal 的所有一切,都可以從這裡窺探出端倪,然後可以選擇感興趣的內容加以繼續深入學習。

本文就先介紹到這裡了,原創不易,如果對你有所幫助請你為本文點個【在看】吧,這將是我寫作更多優質文章的最強動力。

文章的最後分享一位與筆者同樣優秀的知識創造者,樂於分享者的公眾號,建議大家關注一波,或許會有意想不到的收穫。

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

丁威
素質三連是對我最大的鼓勵

分享到: