如何保證 Mysql 數據庫到 ES 的數據一致性
1. 業務場景介紹
1.1 需求分析
某知名的在線旅遊平臺,在即將到來的春季促銷活動之前,決定推出一項新的功能:用戶可以通過輸入目的地、酒店名稱、房型、價格範圍等屬性來搜索旅遊優惠酒店。爲了及時上線這一功能,運營團隊需要將現有的酒店數據同步到高效的搜索引擎中,以支持用戶的高頻搜索需求。
-
功能需求:按目的地、酒店名稱、房型、價格範圍等屬性進行全模糊搜索酒店信息。
-
非功能需求:
-
性能:預計春季促銷期間酒店搜索的 QPS 將達到 1000 左右,搜索結果會包含豐富的酒店信息。
-
響應時間:搜索響應時間需控制在 500 毫秒以內,以確保良好的用戶體驗。
-
數據一致性:確保搜索結果反映的是最新的酒店信息及可用性。
1.2 技術實現方案
假設底層使用 MySQL 數據庫存儲酒店數據,以下是實現該需求的技術方案:
-
數據同步:利用 MySQL 的 binlog 或第三方數據同步工具(如 Debezium、Canal 等)來實時監聽酒店數據的變更,並將這些變更同步到 Elasticsearch 中。
-
索引構建:在 Elasticsearch 中爲目的地、酒店名稱、房型、價格範圍等字段建立合適的索引,以支持快速和高效的模糊搜索。
通過將數據從 MySQL 實時同步到 Elasticsearch,並優化查詢性能,我們可以實現一個快速、準確的酒店搜索功能,滿足春季促銷期間的高併發搜索需求。
思考: 如何保證 Mysql 數據庫和 ES 的數據一致性?
2. 業界常用數據一致性方案分析
在確保 My 數據庫和 Elasticsearch(ES)數據一致性方面,業界有幾種常見的方案:
- 同步雙寫方案
在代碼中對數據庫和 ES 進行雙寫操作,確保先更新數據庫後更新 ES。如果數據庫更新成功而 ES 更新失敗,可以通過事務回滾來保證一致性。這種方案簡單易實現,但可能存在性能瓶頸和不一致的風險。
- MQ 異步雙寫方案
使用消息隊列(如 RocketMQ、Kafka 等)作爲中間件,應用程序在更新數據庫後發送消息到 MQ,由 MQ 的消費者異步更新 ES。這種方案可以解耦數據庫和 ES,提高性能,但可能存在消息延遲和系統複雜度增加的問題。
- 掃表定時同步方案
通過定時任務定期掃描數據庫,將變更的數據同步到 ES。這種方案的實時性較差,但可以減少對數據庫的即時壓力。
- 監聽 binlog 同步方案
通過直接監聽 MySQL 的 binlog 來實現數據庫和 ES 之間的實時同步。這種方案對業務代碼沒有侵入性,可以實現數據庫和 ES 的實時同步,但需要額外的框架和可能存在一定的延遲。
2.1 同步雙寫方案
實現思路
在數據寫入 MySQL 的同時,直接將相同的數據寫入 ES。
優缺點對比
優點
-
數據一致性:雙寫策略可以保證在 MySQL 和 Elasticsearch 之間數據的強一致性,因爲每次數據庫的變更都會在 Elasticsearch 中同步反映。
-
實時性:雙寫策略可以實現數據的實時同步,用戶在 MySQL 中進行的任何操作都會立即在 Elasticsearch 中體現。
-
易於實現:從技術角度來說,雙寫策略的實現相對簡單,通常只需要在應用程序代碼中添加額外的寫入邏輯。
缺點
-
代碼複雜性:需要在應用程序中增加額外的代碼來處理數據的雙寫,這會增加代碼的複雜性和維護難度。
-
性能開銷:每次數據庫操作都需要執行兩次,這會導致額外的性能開銷,尤其是在高併發的場景下。
-
數據不一致風險
:在雙寫過程中,如果發生系統故障或網絡延遲,可能會出現數據不一致的情況,尤其是在寫入 MySQL 成功但寫入 ES 失敗時。
應用場景
系統特點: 舊系統年限長、單體架構且技術比較落後, 如果引入除 es 之外的其他中間件治理成本很高,可以考慮這個方案。
業務場景: 用戶量少、偏後臺管理類的系統,對數據同步的實時性要求很高, 接近實時。
2.2 MQ 異步雙寫方案
實現思路
使用消息隊列(如 RocketMQ、Kafka 等)作爲中間件,應用程序在更新數據庫後發送消息到 MQ,由 MQ 的消費者異步更新 ES。
方案核心
-
生產者端雙寫:生產者系統在發送消息到 MQ 的同時,也寫入到 Mysql。
-
消費者端異步處理:消費者從 MQ 中讀取消息,並異步地將消息處理結果寫入到 ES。
優缺點對比
優點
-
系統解耦:MQ 的使用使得 MySQL 和 ES 之間的依賴性降低,提高了系統的可維護性和擴展性。
-
高可用性:MQ 可以提供消息的持久化存儲,確保即使系統故障,消息也不會丟失。
-
容錯性:在雙寫過程中,即使某個系統出現故障,數據仍然可以通過其他系統恢復。
缺點
-
延遲:異步處理可能會導致數據同步的延遲,特別是在高負載或系統資源不足的情況下。
-
複雜度:引入 MQ 和雙寫機制增加了系統的複雜度,需要更多的開發和維護工作。
-
補償機制:需要設計複雜的補償機制來處理同步失敗的情況,增加了系統的複雜性。
應用場景
系統特點:
-
C 端系統:該系統面向最終用戶,可能是移動應用、Web 應用或桌面應用。
-
引入 MQ 中間件:系統架構中已經包含了消息隊列中間件,這爲異步處理提供了基礎。
-
接口 TPS 性能要求:系統對接口的吞吐量(TPS,Transactions Per Second)有一定要求,需要保證高併發情況下的性能。
業務場景:
-
用戶體量大,高併發場景:系統服務的大量用戶同時進行操作,導致系統面臨高併發壓力。
-
業務變更少:業務邏輯變更相對較少,數據同步的需求比較穩定。
-
允許一定的延遲:在保證用戶體驗的前提下,數據同步的延遲在秒級範圍內是可以接受的。
2.3 掃表定期同步方案
實現思路
通過定時任務定期掃描數據庫,將變更的數據同步到 ES。
優缺點對比
優點
-
實現簡單:使用定時任務調度框架,不需要複雜的開發工作。
-
適合批量數據:對於大量數據的遷移,批量處理可以減少網絡傳輸次數和 ES 的寫入壓力。
-
對業務影響小:定時任務可以在系統負載較低的時段運行,對在線業務影響較小。
缺點
-
實時性差:由於是定期執行,數據同步存在延遲,不適合對實時性要求高的應用。
-
性能影響:同步過程中可能會對 MySQL 和 ES 的性能產生短期影響,尤其是在數據量大時。
-
數據一致性:如果在同步週期內數據發生變化,可能會導致 ES 中數據與 MySQL 不一致。
應用場景
系統特點: 舊系統年限長、技術框架老舊,引入其他的中間件成本很高。
業務場景: 用戶體量小、偏報表統計類業務、對數據實時性要求不高。
2.4 監聽 binlog 同步方案
實現思路
通過直接監聽 MySQL 的 binlog 來實現數據庫和 ES 之間的實時同步。
在高併發場景下,直接將 binlog 事件推送到 ES 可能會導致 ES 負載過高。Kafka 可以作爲緩衝層,暫時存儲 binlog 事件,平滑數據流,避免瞬時的高負載。
優缺點對比
優點
-
業務無侵入,數據同步準實時
-
業務解耦,不需要關注原來系統的業務邏輯。
缺點
-
構建 Binlog 系統複雜;
-
如果採用 MQ 消費解析的 Binlog 信息,也會像方案二一樣存在 MQ 延時的風險。
應用場景
系統特點: c 端系統,開放 mysql binlog 日誌監聽,引入第三方 canal 中間件成本不高。
業務場景: 互聯網公司,用戶體量大、大型多中心組織、高併發場景,業務上允許有一定的延遲 (秒級)。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/OglpvJb2Aejf93OSrGPX0Q