WordPress網(wǎng)站論文微信小程序開發(fā)文檔
文章目錄
- 1. 同步雙寫
- 優(yōu)點(diǎn)
- 缺點(diǎn)
- 實(shí)現(xiàn)方式
- 2. 異步雙寫
- 優(yōu)點(diǎn)
- 缺點(diǎn)
- 實(shí)現(xiàn)方式
- 3. 另起應(yīng)用 SQL 查詢寫入
- 優(yōu)點(diǎn)
- 缺點(diǎn)
- 實(shí)現(xiàn)方式
- 4. Binlog 實(shí)時(shí)同步
- 優(yōu)點(diǎn)
- 缺點(diǎn)
- 實(shí)現(xiàn)方式
- 5. 應(yīng)用場(chǎng)景
本文參考:
- https://www.bilibili.com/video/BV13hvZeaErr/?vd_source=b7e4d17fd13ffa91c4da6d37c08a6c7c
最近在重構(gòu)某個(gè)老系統(tǒng),其大部分查詢邏輯都是做在 MySQL 存儲(chǔ)層上的,當(dāng)面臨一些復(fù)雜的過濾邏輯以及分頁邏輯時(shí),都需要后端工程師根據(jù)前端傳參做一些定制邏輯,后端項(xiàng)目上線發(fā)布的人力成本較大,并且大部分過濾邏輯都是在后端代碼內(nèi)部做的,代碼可讀性與復(fù)用性都不高。同時(shí)隨著時(shí)間的遷移,數(shù)據(jù)庫的數(shù)據(jù)量越來越多,核心首頁接口的耗時(shí)碰到了瓶頸。為了項(xiàng)目未來的發(fā)展,于是決定將原項(xiàng)目重構(gòu),進(jìn)行讀寫異構(gòu)分離建設(shè),寫入 MySQL,查詢走 ES。于是調(diào)研了一下 MySQL 數(shù)據(jù)寫入 ES 的一些方式,簡(jiǎn)要分析各個(gè)方案的優(yōu)缺點(diǎn)。
主要包含以下 4 種方案:
- 同步雙寫
- 異步雙寫
- 另起應(yīng)用 SQL 查詢寫入
- Binlog 實(shí)時(shí)同步
1. 同步雙寫
數(shù)據(jù)寫入 MySQL 的同時(shí),通過編程邏輯將相同邏輯寫入 ES
優(yōu)點(diǎn)
-
實(shí)時(shí)性
數(shù)據(jù)變更能直連寫入 ES,近乎保證了 ES 的實(shí)時(shí)性
-
簡(jiǎn)單性
實(shí)現(xiàn)起來比較簡(jiǎn)單,不需要引入額外的組件,也不需要復(fù)雜的邏輯
缺點(diǎn)
-
性能影響
應(yīng)用內(nèi)部每次寫入 MySQL 同時(shí)寫入 ES,會(huì)對(duì)兩個(gè)系統(tǒng)同時(shí)產(chǎn)生影響
-
數(shù)據(jù)一致性風(fēng)險(xiǎn)
如果雙寫失敗,比方說寫入 MySQL 以后應(yīng)用宕機(jī)未寫入 ES,兩者數(shù)據(jù)不一致
-
系統(tǒng)耦合
? 每個(gè)寫入操作都需要雙寫邏輯,增加了業(yè)務(wù)的復(fù)雜性和維護(hù)難度
-
集群容災(zāi)差
如果要實(shí)現(xiàn)多集群容災(zāi)寫入,相同的寫入邏輯需要往每個(gè)集群都做一次
實(shí)現(xiàn)方式
分別調(diào)用 MySQL 和 ES 的 Client SDK 雙寫即可
2. 異步雙寫
利用消息隊(duì)列異步處理數(shù)據(jù)寫入操作
優(yōu)點(diǎn)
-
性能提升
MQ 異步處理,減少了接口同步等待的時(shí)間
-
容錯(cuò)性
消息隊(duì)列有持久化和重試機(jī)制,提高了 ES 數(shù)據(jù)同步的可靠性 -
集群容災(zāi)水平高
MQ 消息可以被不同集群的 ES 消費(fèi)者組監(jiān)聽
缺點(diǎn)
-
數(shù)據(jù)延遲
異步處理數(shù)據(jù)延遲較高
-
系統(tǒng)復(fù)雜度
需要引入消息隊(duì)列和額外的消費(fèi)邏輯,增加了系統(tǒng)的復(fù)雜度
-
數(shù)據(jù)一致性風(fēng)險(xiǎn)
雖然消息隊(duì)列具有持久化機(jī)制,可以重試保證最終一致,但是當(dāng)應(yīng)用寫入 MySQL 但是還未將消息投遞到消息隊(duì)列時(shí),仍然具有一致性的風(fēng)險(xiǎn)
實(shí)現(xiàn)方式
- 首先需要接入消息隊(duì)列,在應(yīng)用代碼中編寫生產(chǎn)者邏輯
- ES 側(cè)也需要有消費(fèi)者的邏輯
3. 另起應(yīng)用 SQL 查詢寫入
通過定時(shí)任務(wù)或者單獨(dú)起一個(gè)應(yīng)用,去查詢數(shù)據(jù)庫中的某個(gè)時(shí)間段內(nèi)的記錄,并作轉(zhuǎn)換邏輯同步至 ES
優(yōu)點(diǎn)
-
性能提升
也是異步處理,減少了接口同步等待的時(shí)間
-
無侵入性
不需要修改原有的業(yè)務(wù)邏輯,原系統(tǒng)對(duì)此無感知
缺點(diǎn)
-
時(shí)效性差
定時(shí)任務(wù)或者應(yīng)用 RPC 拉取仍然存在延遲 -
性能壓力
查詢某一時(shí)間段數(shù)據(jù)會(huì)對(duì)原來的數(shù)據(jù)庫產(chǎn)生額外的查詢壓力 -
集群容災(zāi)差
如果要實(shí)現(xiàn)多集群容災(zāi)寫入,相同的寫入邏輯需要往每個(gè)集群都做一次
實(shí)現(xiàn)方式
- 維護(hù)時(shí)間戳字段,方便每次查詢出新時(shí)間段的記錄
- 定時(shí)任務(wù)/應(yīng)用代碼邏輯單獨(dú)上線
4. Binlog 實(shí)時(shí)同步
利用 MySQL 的 Binlog 日志,通過消息隊(duì)列消費(fèi)變化來同步至 ES
優(yōu)點(diǎn)
-
性能提升
也是異步處理,減少了接口同步等待的時(shí)間
-
無侵入性
不需要修改原有的業(yè)務(wù)邏輯,原系統(tǒng)對(duì)此無感知 -
數(shù)據(jù)一致性
MySQL Binlog 可以精準(zhǔn)捕捉到數(shù)據(jù)庫的所有變更 -
容錯(cuò)性
通常搭配 MQ 使用,在網(wǎng)絡(luò)波動(dòng)下仍然能夠重試,保證數(shù)據(jù)的最終一致;并且 MQ 還具有一定的削峰作用,對(duì) ES 寫入較友好
缺點(diǎn)
- 系統(tǒng)復(fù)雜度
需要維護(hù) Binlog 日志監(jiān)聽和消息隊(duì)列系統(tǒng),增加了系統(tǒng)的復(fù)雜度 - 延遲問題
“準(zhǔn)實(shí)時(shí)”同步,但是其中涉及到不同組件間的網(wǎng)絡(luò)傳輸較多,相比于直連寫入 ES 延遲較大
實(shí)現(xiàn)方式
- MySQL Binlog 日志開啟
- Binlog 監(jiān)聽器配置
- 消息隊(duì)列集成,確保 Binlog 變更能夠發(fā)送到消息隊(duì)列中
- 消費(fèi)者邏輯開發(fā),從消息隊(duì)列中讀取 Binlog 并轉(zhuǎn)換成 ES 可以理解的格式
5. 應(yīng)用場(chǎng)景
-
在公司內(nèi)部通常都采用第4種解決方案,通常都有內(nèi)部的平臺(tái)使用,實(shí)現(xiàn)存量數(shù)據(jù)和增量數(shù)據(jù)的遷移,前面兩種方式還需要修改原有的邏輯代碼。
-
如果追求時(shí)效性的話,可以增加冗余寫入鏈路,比方說直連寫入 + 異步寫入,保證一致性的同時(shí)增強(qiáng)時(shí)效性,但是注意處理 ES 的沖突解決策略,通常兩條相同記錄的寫入采用的是替換 Replace 策略。