MySQL資料同步ES的4種方法,你能想到幾種?

語言: CN / TW / HK

大家好,我是老三,這期給大家分享一個電商中常見的場景——MySQL資料同步Elasticsearch。

商品檢索

大家應該都在各種電商網站檢索過商品,那麼檢索商品一般都是通過什麼實現呢?搜尋引擎Elasticsearch。

那麼問題來了,商品上架,資料一般寫入到MySQL的資料庫中,那麼用於檢索的資料又是怎麼同步到Elasticsearch的呢?

MySQL同步ES

1.同步雙寫

這是能想到的最直接的方式,在寫入MySQL,直接也同步往ES裡寫一份資料。

同步雙寫

對於這種方式:

  • 優點:實現簡單
  • 缺點:
  • 業務耦合,商品的管理中耦合大量資料同步程式碼
  • 影響效能,寫入兩個儲存,響應時間變長
  • 不便擴充套件:搜尋可能有一些個性化需求,需要對資料進行聚合,這種方式不便實現

2.非同步雙寫

我們也很容易想到非同步雙寫的辦法,上架商品的時候,先把商品資料丟進MQ,為了解耦合,我們一般會拆分一個搜尋服務,由搜尋服務去訂閱商品變動的訊息,來完成同步。

非同步雙寫

前面說的,一些資料需要聚合處理成類似寬表的結構怎麼辦呢?例如商品庫的商品品類、spu、sku表是分開的,但是查詢是跨維度的,在ES裡再聚合一次效率就低一些,最好就是把商品的資料給聚合起來,在ES裡以類似大寬表的形式儲存,這樣一來查詢效率就高一些。

多維度多條件查詢

這種其實沒什麼好辦法,基本上還是得搜尋服務直接查庫,或者遠端呼叫,再查詢一遍商品的資料庫,就是所謂的回查。

回查完成聚合

這種方式:

  • 優點:
  • 解耦合,商品服務無需關注資料同步
  • 實時性較好,使用MQ,正常情況下,同步完成在秒級
  • 缺點:
  • 引入了新的元件和服務,增加了複雜度

3.定時任務

假如我們要快速搞搞,資料量有沒那麼大,怎麼辦呢?定時任務也可以。

定時任務

定時任務,最麻煩的一點是頻率不好選,頻率高的話,會非自然地形成業務的波峰,導致儲存的CPU、記憶體佔用波峰式上升,頻率低的話實時性比較差,而且也有波峰的情況。

這種方式:

  • 優點:實現比較簡單
  • 缺點:
  • 實時性難以保證
  • 對儲存壓力較大

4.資料訂閱

還有一種方式,就是最時興的資料訂閱。

MySQL通過binlog訂閱實現主從同步,各路資料訂閱框架比如canal就依據這個原理,將client元件偽裝成從庫,來實現資料訂閱。

MySQL主從同步

我們以應用最廣泛的canal為例,canal通過canal-adapter,支援多種介面卡,其中就有ES介面卡,通過一些配置,啟動之後,就可以直接把MySQL資料同步到ES,這個過程是零程式碼的。

canal同步資料

但是,和老闆瞭解過,使用canal看起來很美好,幫我們把同步的事情都幹了,但其實,還是要寫程式碼。為什麼呢?

前面提到的多張表資料聚合,canal的支援沒那麼好,所以還是得回查。這時候用canal-adapter就不合適了,需要自己實現canal-client,監聽和聚合資料,寫入ES:

資料訂閱+回查

這種看起來和非同步雙寫比較像,但是第一降低了商品服務的耦合,第二資料的實時性更好。

所以使用資料訂閱:

  • 優點:
  • 業務入侵較少
  • 實時性較好

至於資料訂閱框架的選型,主流的大體上是這些:

| | Cancal | Maxwell | Python-Mysql-Rplication | | -------- | ----------------------- | ----------------------- | ----------------------- | | 開源方 | 阿里巴巴 | Zendesk | 社群 | | 開發語言 | Java | Java | Python | | 活躍度 | 活躍 | 活躍 | 活躍 | | 高可用 | 支援 | 支援 | 不支援 | | 客戶端 | Java/Go/PHP/Python/Rust | 無 | Python | | 訊息落地 | Kafka/RocketMQ 等 | Kafka/RabbitNQ/Redis 等 | 自定義 | | 訊息格式 | 自定義 | JSON | 自定義 | | 文件詳略 | 詳細 | 詳細 | 詳細 | | Boostrap | 不支援 | 支援 | 不支援 |

除了MySQL同步ES,MySQL同步到其它的資料儲存,例如HBase,其實大體上都是類似的幾種方法。



參考:

[1]. http://www.infoq.cn/article/1afyz3b6hnhprrg12833

[2].http://www.iamle.com/archives/2900.html

[3].http://blog.51cto.com/lianghecai/4755693

[4].http://qinyuanpei.github.io/posts/1333693167/

[5].http://github.com/alibaba/canal/wiki/ClientAdapter