需求
在現代的系統開發中, 為了提高搜索效率 , 以及搜索的精准度, 會大量的使用 redis ,memcache 等 nosql 系統的數據庫 , 以及 solr , elasticsearch 類似的全文檢索服務; 那么這個時候, 就又有一個問題需要我們來考慮, 就是數據同步的問題, 如何將實時變化的數據庫中的數據同步到 solr 的索引庫中或者 redis 中呢 ?
1 數據同步方案
1.1 方案一: 業務代碼中同步
在增加、修改、刪除之后,執行操作solr索引庫的邏輯代碼。
優點 : 操作簡便
缺點 :
-
業務耦合度高
-
執行效率變低
1.2 方案二: 定時任務同步
在執行完增加、修改、刪除,操作數據庫中的數據變更之后 ,通過定時任務定時的將數據庫的數據同步到solr的索引庫中。
定時任務技術 : SpringTask , Quartz
優點:同步solr索引庫操作與業務代碼完全解耦。
缺點:數據的實時性並不高。
1.3 方案三: 通過MQ實現同步
在執行完增加、修改、刪除之后, 往MQ中發送一條消息 ;同步程序作為MQ中的消費者,從消息隊列中獲取消息,然后執行同步solr索引庫的邏輯。
優點:業務代碼解耦, 並且可以做到准實時
缺點:需要在業務代碼中加入發送消息到MQ中的代碼 , API耦合
1.4 方案四: 通過Canal實現實時同步
通過Canal來解析數據庫的日志信息, 來檢測數據庫中表結構的數據變化,從而更新solr索引庫。
優點:業務代碼完全解耦,API完全解耦,可以做到准實時。
缺點:無
2 Canal介紹
2.1 Canal概述
阿里巴巴 mysql 數據庫 binlog 的增量訂閱 & 消費組件。
名稱: canal [kə'næl]
譯意: 水道 / 管道 / 溝渠
語言: 純 java 開發
定位: 基於數據庫增量日志解析,提供增量數據訂閱 & 消費,目前主要支持了 mysql
關鍵詞: mysql binlog parser / real-time / queue&topic
1.1 Canal下載
官網: https://github.com/alibaba/canal
這里選擇了Canal的1.1.4版本.
下載壓縮包
canal.deployer-1.1.4.tar.gz : 這個是canal Server的部署包
canal.example-1.1.4.tar.gz : 這個是樣例
Source code(zip) : 是canal的源碼包
3 Canal工作原理
3.1 mysql主從同步實現
原理:
從上層來看,主從復制分成三步:
-
master 將改變記錄到二進制日志 (binary log) 中(這些記錄叫做二進制日志事件, binary log events ,可以通過 show binlog events 進行查看);
-
slave 將 master 的 binary log events 拷貝到它的中繼日志 (relay log);
-
slave 重做中繼日志中的事件將改變反映它自己的數據。
3.2 Canal內部原理
原理圖:
原理相對比較簡單:
-
canal 模擬 mysql slave 的交互協議,偽裝自己為 mysql slave ,向 mysql master 發送 dump 協議。
-
mysql master 收到 dump 請求,開始推送 binary log 給 slave( 也就是 canal) 。
-
canal 解析 binary log 對象 ( 原始為 byte 流 ) 。
3.3 Canal內部結構
說明:
-
Server : 代表一個canal運行實例,對應於一個jvm
-
Instance : 對應於一個數據隊列 (1個server對應1..n個instance)
instance下的子模塊:
eventParser : (數據源接入,模擬slave協議和master進行交互,協議解析)
eventSink : (Parser和Store鏈接器,進行數據過濾,加工,分發的工作)
eventStore : (數據存儲)
metaManager : (增量訂閱&消費信息管理器)