MySQL中的半同步復(fù)制

MySQL當(dāng)前存在的三種復(fù)制模式有:異步模式、半同步模式和組復(fù)制模式。注意:MySQL復(fù)制模式?jīng)]有“同步復(fù)制”這一項(xiàng)的,文章中只是為了讀者方便理解半同步復(fù)制的概念才介紹了同步復(fù)制概念https://dev.mysql.com/doc/refman/8.0/en/replication-semisync.html

從MySQL5.5開始,MySQL以插件的形式支持半同步復(fù)制。

1. 異步復(fù)制(Asynchronous replication)

MySQL默認(rèn)的復(fù)制即是異步的,主庫在執(zhí)行完客戶端提交的事務(wù)后會立即將結(jié)果返給給客戶端,并不關(guān)心從庫是否已經(jīng)接收并處理,這樣就會有一個(gè)問題,主如果crash掉了,此時(shí)主上已經(jīng)提交的事務(wù)可能并沒有傳到從上,如果此時(shí),強(qiáng)行將從提升為主,可能導(dǎo)致新主上的數(shù)據(jù)不完整。

異步復(fù)制是MySQL最早的也是當(dāng)前使用最多的復(fù)制模式,異步復(fù)制提供了一種簡單的主-從復(fù)制方法,包含一個(gè)主庫(master)和備庫(一個(gè),或者多個(gè)) 之間,主庫執(zhí)行并提交了事務(wù),在這之后(因此才稱之為異步),這些事務(wù)才在從庫上重新執(zhí)行一遍(基于statement)或者變更數(shù)據(jù)內(nèi)容(基于 row),主庫不檢測其從庫上的同步情況。在服務(wù)器負(fù)載高、服務(wù)壓力大的情況下主從產(chǎn)生延遲一直是其詬病。工作流程簡圖如下:

而同步復(fù)制(Fully synchronous replication,MySQL中沒有此復(fù)制概念)指當(dāng)主庫執(zhí)行完一個(gè)事務(wù),所有的從庫都執(zhí)行了該事務(wù)才返回給客戶端。因?yàn)樾枰却袕膸靾?zhí)行完該事務(wù)才能返回,所以全同步復(fù)制的性能必然會收到嚴(yán)重的影響。

2. 半同步復(fù)制(Semisynchronous replication)

介于異步復(fù)制和全同步復(fù)制之間,主庫在執(zhí)行完客戶端提交的事務(wù)后不是立刻返回給客戶端,而是等待至少一個(gè)從庫接收到并寫到relay log中才返回給客戶端。相對于異步復(fù)制,半同步復(fù)制提高了數(shù)據(jù)的安全性,同時(shí)它也造成了一定程度的延遲,這個(gè)延遲最少是一個(gè)TCP/IP往返的時(shí)間。所以,半同步復(fù)制最好在低延時(shí)的網(wǎng)絡(luò)中使用。

MySQL5.5 的版本在異步同步的基礎(chǔ)之上,以插件的形式實(shí)現(xiàn)了一個(gè)變種的同步方案,稱之為半同步復(fù)制(semi-sync replication)。這個(gè)插件在原生的異步復(fù)制上,添加了一個(gè)同步的過程:當(dāng)從庫接收到了主庫的變更(即事務(wù))時(shí),會通知主庫。主庫上的操作有兩種:接收到這個(gè)通知以后才去commit事務(wù);接受到之后釋放session。這兩種方式是由主庫上的具體配置決定的。當(dāng)主庫收不到從庫的變更通知超時(shí)時(shí),由半同步復(fù)制自動切換到異步同步,這樣就極大了保證了數(shù)據(jù)的一致性(至少一個(gè)從庫),但是在性能上有所下降,特別是在網(wǎng)絡(luò)不穩(wěn)定的情況下,半同步和同步之間來回切換,對正常的業(yè)務(wù)是有影響的。其工作流程簡圖如下:

3、Group Replication(組復(fù)制)

不論是異步復(fù)制還是半同步復(fù)制,都是一個(gè)主下面一個(gè)從或是多個(gè)從的模式,在高并發(fā)下高負(fù)載下,都存在延遲情況,此時(shí)如果主節(jié)點(diǎn)出現(xiàn)異常,那么就會出現(xiàn)數(shù)據(jù)不 一致的情況,數(shù)據(jù)可能會丟,在金融級數(shù)據(jù)庫中是不能容忍的。在這種情況下,急需出現(xiàn)一種模式來解決這些問題。在MySQL5.7.17的版本中,帶著這些期待,新的復(fù)制模式“組復(fù)制"由此產(chǎn)生并GA了。

組復(fù)制的工作流程圖如下:

組復(fù)制的工作原理

MySQL組復(fù)制是一個(gè)MySQL插件,它建立在現(xiàn)有的MySQL復(fù)制基礎(chǔ)結(jié)構(gòu)上,利用了二進(jìn)制日志,基于行的日志記錄和全局事務(wù)標(biāo)識符等功能。它集成了當(dāng)前的MySQL框架,如性能模式、插件和服務(wù)基礎(chǔ)設(shè)施等。

組復(fù)制(Group Replication)基于分布式一致性算法(Paxos協(xié)議的變體)實(shí)現(xiàn),一個(gè)組允許部分節(jié)點(diǎn)掛掉,只要保證絕大多數(shù)節(jié)點(diǎn)仍然存活并且之間的通訊是沒有問題的,那么這個(gè)組對外仍然能夠提供服務(wù),它是一種被使用在容錯(cuò)系統(tǒng)中的技術(shù)。Group Replication(復(fù)制組)是由能夠相互通信的多個(gè)服務(wù)器(節(jié)點(diǎn))組成的。在通信層,Group replication實(shí)現(xiàn)了一系列的機(jī)制:比如原子消息(atomic message delivery)和全序化消息(totalordering of messages)。這些原子化、抽象化的機(jī)制,為實(shí)現(xiàn)更先進(jìn)的數(shù)據(jù)庫復(fù)制方案提供了強(qiáng)有力的支持。

MySQL Group Replication正是基于這些技術(shù)和概念,實(shí)現(xiàn)了一種多主全更新的復(fù)制協(xié)議。簡而言之,一個(gè)Group Replication就是一組節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)都可以獨(dú)立執(zhí)行事務(wù),而讀寫事務(wù)則會在于group內(nèi)的其他節(jié)點(diǎn)進(jìn)行協(xié)調(diào)之后再commit。因此,當(dāng)一個(gè)事務(wù)準(zhǔn)備提交時(shí),會自動在group內(nèi)進(jìn)行原子性的廣播,告知其他節(jié)點(diǎn)變更了什么內(nèi)容/執(zhí)行了什么事務(wù)。這種原子廣播的方式,使得這個(gè)事務(wù)在每一個(gè)節(jié)點(diǎn)上都保持著同樣順序。這意味著每一個(gè)節(jié)點(diǎn)都以同樣的順序,接收到了同樣的事務(wù)日志,所以每一個(gè)節(jié)點(diǎn)以同樣的順序重演了這些事務(wù)日志,最終整個(gè)group保持了完全一致的狀態(tài)。然而,不同的節(jié)點(diǎn)上執(zhí)行的事務(wù)之間有可能存在資源爭用。這種現(xiàn)象容易出現(xiàn)在兩個(gè)不同的并發(fā)事務(wù)上。假設(shè)在不同的節(jié)點(diǎn)上有兩個(gè)并發(fā)事務(wù),更新了同一行數(shù)據(jù),那么就會發(fā)生資源爭用。面對這種情況,Group Replication判定先提交的事務(wù)為有效事務(wù),會在整個(gè)group里面重放,后提交的事務(wù)會直接中斷,或者回滾,最后丟棄掉。因此,這也是一個(gè)無共享的復(fù)制方案,每一個(gè)節(jié)點(diǎn)都保存了完整的數(shù)據(jù)副本。

從其工作的原理可以看出,Group Replication基于Paxos協(xié)議的一致性算法校驗(yàn)事務(wù)執(zhí)行是否有沖突,然后順序執(zhí)行事務(wù),達(dá)到最終的數(shù)據(jù)一致性,也就意味著部分節(jié)點(diǎn)可以存在延遲??梢栽O(shè)置多主同時(shí)寫入和單主寫入,通過設(shè)置 group_replication_single_primary_mode 來進(jìn)行控制是多主還是單主,官方推薦單主寫入,允許延遲,但延遲過大,則會觸發(fā)限流規(guī)則(可配置的),整個(gè)集群會變的很慢,性能大打折扣。

更多組復(fù)制: http://www.sohu.com/a/124913450_354963

半同步復(fù)制的潛在問題

客戶端事務(wù)在存儲引擎層提交后,在得到從庫確認(rèn)的過程中,主庫宕機(jī)了,此時(shí),可能的情況有兩種:

1. 事務(wù)還沒發(fā)送到從庫上

此時(shí),客戶端會收到事務(wù)提交失敗的信息,客戶端會重新提交該事務(wù)到新的主上,當(dāng)宕機(jī)的主庫重新啟動后,以從庫的身份重新加入到該主從結(jié)構(gòu)中,會發(fā)現(xiàn),該事務(wù)在從庫中被提交了兩次,一次是之前作為主的時(shí)候,一次是被新主同步過來的。

2. 事務(wù)已經(jīng)發(fā)送到從庫上

此時(shí),從庫已經(jīng)收到并應(yīng)用了該事務(wù),但是客戶端仍然會收到事務(wù)提交失敗的信息,重新提交該事務(wù)到新的主上。

無數(shù)據(jù)丟失的半同步復(fù)制

針對上述潛在問題,MySQL 5.7引入了一種新的半同步方案:Loss-Less半同步復(fù)制。

針對上面這個(gè)圖,“Waiting Slave dump”被調(diào)整到“Storage Commit”之前。

當(dāng)然,之前的半同步方案同樣支持,MySQL 5.7.2引入了一個(gè)新的參數(shù)進(jìn)行控制-rpl_semi_sync_master_wait_point

rpl_semi_sync_master_wait_point有兩種取值

AFTER_SYNC

這個(gè)即新的半同步方案,Waiting Slave dump在Storage Commit之前。

AFTER_COMMIT

老的半同步方案,如圖所示。

三種復(fù)制方案的區(qū)別

異步復(fù)制

MySQL復(fù)制默認(rèn)是異步復(fù)制,Master將事件寫入binlog,提交事務(wù),自身并不知道slave是否接收是否處理;

缺點(diǎn):不能保證所有事務(wù)都被所有slave接收。

同步復(fù)制(MySQL中不存在此模式)

Master提交事務(wù),直到事務(wù)在所有slave都已提交,才會返回客戶端事務(wù)執(zhí)行完畢信息;

缺點(diǎn):完成一個(gè)事務(wù)可能造成延遲。

半同步復(fù)制

當(dāng)Master上開啟半同步復(fù)制功能時(shí),至少有一個(gè)slave開啟其功能。當(dāng)Master向slave提交事務(wù),且事務(wù)已寫入relay-log中并刷新到磁盤上,slave才會告知Master已收到;若Master提交事務(wù)受到阻塞,出現(xiàn)等待超時(shí),在一定時(shí)間內(nèi)Master 沒被告知已收到,此時(shí)Master自動轉(zhuǎn)換為異步復(fù)制機(jī)制;

注:半同步復(fù)制功能要在Master和slave上開啟才會起作用,只開啟一邊,依然是異步復(fù)制。

https://blog.haohtml.com/archives/18328

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容