Canal從Mysql獲取binlog日誌的通信過程詳解

簡介

本文主要以Mysql爲例,分析canal的parser模塊是如何從mysql拉取數據的。

核心

canal的官網中介紹到,canal的工作原理簡單分爲如下幾步:

  1. canal模擬mysql slave的交互協議,僞裝自己爲mysql slave,向mysql master發送dump協議
  2. mysql master收到dump請求,開始推送binary log給slave(也就是canal)
  3. canal解析binary log對象(原始爲byte流)

在canal的parser模塊中,有一個抽象類AbstractEventParser,該類中定義了一個線程,該線程每10秒向Mysql的Master節點發送一次dump請求,用於請求binlog日誌數據,然後把binlog數據存儲到一個大小爲1024的ringbuffer緩存隊列中,整個流程如下圖所示:

下面將詳細介紹一個完整的canal請求binlog日誌的過程:

  1. 首先會啓動一個心跳線程,該心跳線程只作用於parser模塊和sink模塊,每秒向sink模塊推送一個心跳報文。

  2. 在創建與Mysql節點的連接之前,需要做一些準備工作,比如確定binlog的FORMAT以及binlog_row_image參數的值

  3. 建立與Mysql的連接,在instance.properties文件中會配置Master的地址端口以及對應的數據庫用戶名密碼,此處就是利用這些信息建立與Master的連接。

  4. 獲取到Mysql的ServerId

  5. 獲取最後的位置信息,也就是上一次與Master通信後讀取到的binlog的位置,該位置信息也會寫入meta.dat文件中,因此如果內存中沒有,會嘗試從該文件中讀取。

  6. 重新鏈接,因爲在找position過程中可能有狀態變更,需要斷開後重建。

  7. 調用dump()方法開始獲取pbinglog數據,同時註冊一個回調事件用於接收返回的binlog數據。

  8. sleep10秒,重新執行上述流程。

當有回調事件返回時,處理流程如下

  1. 調用BinlogParser類的parse()方法將返回的二進制binlog數據LogEvent,解析成canal封裝好的Entry事件,LogEvent中包含一個事件類型eventType,詳細區分了該事件是查詢操作還是寫操作,或者是心跳等各種類型。
  2. 調用EventTransactionBuffer類的add()方法將Entry事件添加到一個大小爲1024的ringbuffer中。
  3. EventTransactionBuffer會在一定的條件下把ringbuffer中的Entry事件推送到sink模塊。

至此,parser模塊下的canal與mysql的通信過程全部結束。

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