16. 數(shù)據(jù)一致性、安全性保障 | 深入淺出MGR
本文介紹MGR如何保障數(shù)據(jù)一致性及安全性。
1. MGR事務(wù)一致性
對于MGR這樣的"分布式"系統(tǒng)而言,需要在多個節(jié)點(diǎn)間保障事務(wù)的一致性,無論各個節(jié)點(diǎn)狀態(tài)正常,或者個別節(jié)點(diǎn)處于故障修復(fù)狀態(tài),都要能保證各個節(jié)點(diǎn)的事務(wù)數(shù)據(jù)最終一致。所謂的最終一致性是指當(dāng)所有寫事務(wù)請求都停止后,各個節(jié)點(diǎn)上的事務(wù)數(shù)據(jù)是一致的。
與MGR數(shù)據(jù)一致性相關(guān)的因素有這幾種:
- 節(jié)點(diǎn)發(fā)生變化,添加 或 刪除。
- 節(jié)點(diǎn)故障修復(fù)。
- Primary節(jié)點(diǎn)發(fā)生切換。
通過選項(xiàng)group_replication_consistency可以設(shè)置節(jié)點(diǎn)的事務(wù)一致性保障等級。這個選項(xiàng)是從MySQL 8.0.14開始引入的,默認(rèn)值是EVENTUAL,即最終一致性,這也是在8.0.14之前,未引入該選項(xiàng)前MGR的默認(rèn)事務(wù)一致性保障級別。
2. Primary節(jié)點(diǎn)切換時如何保障事務(wù)一致性
在單主模式中,當(dāng)Primary節(jié)點(diǎn)切換時(無論是手動切換還是因?yàn)楣收限D(zhuǎn)移),新的Primary節(jié)點(diǎn)有兩種可選方式應(yīng)對如何處理積壓事務(wù):
1.第一種:不處理積壓事務(wù),立即響應(yīng)讀寫事務(wù)請求。這時,事務(wù)可能會讀取到舊數(shù)據(jù)。
2.第二種:優(yōu)先處理完積壓事務(wù)后再響應(yīng)讀寫事務(wù)請求。這時,新的Primary節(jié)點(diǎn)可能需要耗時更久才能響應(yīng)讀寫事務(wù)請求,這取決于積壓事務(wù)隊(duì)列大小。
在MySQL 8.0.14前,由于不支持設(shè)置事務(wù)一致性等級,選擇了可用性最大化的方案,即上述的第一種方案。
P.S,多主模式下,由于每個節(jié)點(diǎn)都可以響應(yīng)讀寫事務(wù)請求,因此不存在這個問題。
3. 事務(wù)數(shù)據(jù)一致性保障
在MGR中,并不是所有的事件(事務(wù))都是同步的,部分流程是異步的,因此Secondary節(jié)點(diǎn)上可能存在數(shù)據(jù)延遲,也就是說在Secondary上可能讀取到舊事務(wù)數(shù)據(jù)。
從MySQL 8.0.14開始,通過設(shè)置選項(xiàng)group_replication_consistency可以控制RO(只讀)、RW(讀寫)事務(wù)在讀取或?qū)懭霐?shù)據(jù)前的一致性等級,可以避免讀取到舊數(shù)據(jù),或者寫入數(shù)據(jù)后盡快同步到其他節(jié)點(diǎn),以滿足各種不同應(yīng)用場景對事務(wù)一致性等級的要求。
我們先了解幾個基本概念,事務(wù)同步點(diǎn)可分為讀時事務(wù)同步以及寫時事務(wù)同步,結(jié)合MGR的事務(wù)機(jī)制,更具體的說就是事務(wù)執(zhí)行前(BEFORE)和事務(wù)執(zhí)行后(AFTER)。
接下來,我們一一介紹選項(xiàng)group_replication_consistency都有哪些可選等級。
P.S,每個節(jié)點(diǎn)上可以單獨(dú)設(shè)置不同的事務(wù)一致性等級,而且可做session級修改,但是非常不建議這么做。
3.1 EVENTUAL
在這個等級下,RO和RW事務(wù)執(zhí)行前,都不會要求等待積壓事務(wù)先行應(yīng)用完成。
這是默認(rèn)等級,也是在引入該選項(xiàng)前的行為。這意味著以下幾點(diǎn):
- RW事務(wù)無需等待,而可能先于其他節(jié)點(diǎn)進(jìn)行外部化(將事務(wù)廣播到其他節(jié)點(diǎn))。
- RO事務(wù)可能讀取到舊數(shù)據(jù)。
- 在Primary節(jié)點(diǎn)切換時,新產(chǎn)生的RW事務(wù)有可能會因?yàn)闆_突而回滾。
3.2 BEFORE_ON_PRIMARY_FAILOVER
當(dāng)發(fā)生Primary節(jié)點(diǎn)切換時,在新的Primary上需要先等待把所有來自舊Primary節(jié)點(diǎn)的積壓事務(wù)應(yīng)用完畢,之后才能正式完成切換,轉(zhuǎn)成ONLINE狀態(tài),成為新的Primary節(jié)點(diǎn),繼續(xù)響應(yīng)新的事務(wù)請求。
這么做可以保證在發(fā)生故障轉(zhuǎn)移時,客戶端不會查到舊數(shù)據(jù),保證了數(shù)據(jù)一致性,不過客戶端上也可能會產(chǎn)生延遲等待。
3.3 BEFORE
RW事務(wù)在應(yīng)用之前,RO事務(wù)在執(zhí)行之前,都要先等待前面堆積的事務(wù)完成。
這可以保證RO事務(wù)總能讀取到最新事務(wù),但對于RW事務(wù)而言,只是等待堆積事務(wù)應(yīng)用完成,但并不要求其他節(jié)點(diǎn)上也完成該事務(wù)。
3.4 AFTER
它比BEFORE更近一步,要求RW事務(wù)在其他節(jié)點(diǎn)上也要等待應(yīng)用完畢。這樣一來,后續(xù)的事務(wù)在任何節(jié)點(diǎn)上就都能獲取最新事務(wù)數(shù)據(jù)。
事實(shí)上,要慎用該級別及更高以上級別,可能會引發(fā)其他問題,可參考這個文章:技術(shù)分享 | 為什么MGR一致性模式不推薦AFTER
3.5 BEFORE_AND_AFTER
一致性級別要求最高,對RO和RW事務(wù)都要求同步事務(wù)數(shù)據(jù)。也就是說,RW事務(wù)在應(yīng)用之前,要先等待前面堆積的事務(wù)完成,并且還需要等待它的事務(wù)變更在其他所有節(jié)點(diǎn)上也都應(yīng)用;RO事務(wù)在執(zhí)行之前,也要先等待前面堆積的事務(wù)完成。
4. 一致性級別選擇建議
對于絕大多數(shù)場景,使用默認(rèn)的 EVENTUAL 等級就足夠了;尤其是在使用單主模式時,如果需要實(shí)時讀取事務(wù)數(shù)據(jù),只需向Primary節(jié)點(diǎn)發(fā)起請求即可。
進(jìn)一步,如果擔(dān)心Primary節(jié)點(diǎn)切換時會讀取到舊事務(wù)數(shù)據(jù),可以提高到BEFORE_ON_PRIMARY_FAILOVER級別。
更進(jìn)一步,如果希望在Secondary節(jié)點(diǎn)也能及時讀取到最新事務(wù)數(shù)據(jù),以此提高讀擴(kuò)展能力,可以提高到BEFORE級別。
更高的一致性級別就不再建議使用了,潛在的風(fēng)險以及bug比較多。
P.S,各個節(jié)點(diǎn)的一致性級別最好都設(shè)置成一樣,并且在運(yùn)行過程中也不要修改其session級選項(xiàng)值,避免造成不可預(yù)料的影響。
小結(jié)
本文介紹了MGR中幾個不同的數(shù)據(jù)一致性保障等級,以及應(yīng)該選擇何種等級的建議。
參考資料、文檔:
MySQL 8.0 Reference Manual(?https://dev.mysql.com/doc/refman/8.0/en/group-replication.html)。
數(shù)據(jù)庫內(nèi)核開發(fā) - 溫正湖(?https://www.zhihu.com/column/c_206071340)。
Group Replication原理 - 宋利兵(https://mp.weixin.qq.com/s/1iO-KISAU1HLSzEVLrxG9g)?。