MySQL 數據同步 ES 的 4 種方法!你能想到幾種?
大家好,我是老三,這期給大家分享一個電商中常見的場景——MySQL 數據同步 Elasticsearch。
大家應該都在各種電商網站檢索過商品,檢索商品一般都是通過什麼實現呢?搜索引擎 Elasticsearch。
那麼問題來了,商品上架,數據一般寫入到 MySQL 的數據庫中,那麼用於檢索的數據又是怎麼同步到 Elasticsearch 的呢?
1. 同步雙寫
這是能想到的最直接的方式,在寫入 MySQL,直接也同步往 ES 裏寫一份數據。
對於這種方式:
-
優點:實現簡單
-
缺點:
-
業務耦合,商品的管理中耦合大量數據同步代碼
-
影響性能,寫入兩個存儲,響應時間變長
-
不便擴展:搜索可能有一些個性化需求,需要對數據進行聚合,這種方式不便實現
2. 異步雙寫
我們也很容易想到異步雙寫的辦法,上架商品的時候,先把商品數據丟進 MQ,爲了解耦合,我們一般會拆分一個搜索服務,由搜索服務去訂閱商品變動的消息,來完成同步。
前面說的,一些數據需要聚合處理成類似寬表的結構怎麼辦呢?例如商品庫的商品品類、spu、sku 表是分開的,但是查詢是跨維度的,在 ES 裏再聚合一次效率就低一些,最好就是把商品的數據給聚合起來,在 ES 裏以類似大寬表的形式存儲,這樣一來查詢效率就高一些。
這種其實沒什麼好辦法,基本上還是得搜索服務直接查庫,或者遠程調用,再查詢一遍商品的數據庫,就是所謂的回查。
這種方式:
-
優點:
-
解耦合,商品服務無需關注數據同步
-
實時性較好,使用 MQ,正常情況下,同步完成在秒級
-
缺點:
-
引入了新的組件和服務,增加了複雜度
3. 定時任務
假如我們要快速搞搞,數據量有沒那麼大,怎麼辦呢?定時任務也可以。
定時任務,最麻煩的一點是頻率不好選,頻率高的話,會非自然地形成業務的波峯,導致存儲的 CPU、內存佔用波峯式上升,頻率低的話實時性比較差,而且也有波峯的情況。
這種方式:
-
優點:實現比較簡單
-
缺點:
-
實時性難以保證
-
對存儲壓力較大
4. 數據訂閱
還有一種方式,就是最時興的數據訂閱。
MySQL 通過 binlog 訂閱實現主從同步,各路數據訂閱框架比如 canal 就依據這個原理,將 client 組件僞裝成從庫,來實現數據訂閱。
我們以應用最廣泛的 canal 爲例,canal 通過canal-adapter
,支持多種適配器,其中就有 ES 適配器,通過一些配置,啓動之後,就可以直接把 MySQL 數據同步到 ES,這個過程是零代碼的。
但是,和老闆瞭解過,使用 canal 看起來很美好,幫我們把同步的事情都幹了,但其實,還是要寫代碼。爲什麼呢?
前面提到的多張表數據聚合,canal 的支持沒那麼好,所以還是得回查。這時候用 canal-adapter 就不合適了,需要自己實現 canal-client,監聽和聚合數據,寫入 ES:
這種看起來和異步雙寫比較像,但是第一降低了商品服務的耦合,第二數據的實時性更好。
所以使用數據訂閱:
-
優點:
-
業務入侵較少
-
實時性較好
至於數據訂閱框架的選型,主流的大體上是這些:
除了 MySQL 同步 ES,MySQL 同步到其它的數據存儲,例如 HBase,其實大體上都是類似的幾種方法。
參考:
-
[1]. https://www.infoq.cn/article/1afyz3b6hnhprrg12833
-
[2].https://www.iamle.com/archives/2900.html
-
[3].https://blog.51cto.com/lianghecai/4755693
-
[4].https://qinyuanpei.github.io/posts/1333693167/
-
[5].https://github.com/alibaba/canal/wiki/ClientAdapter
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/-srzkEGr5uxyWw_OBk6dQg