本文介紹MGR的故障檢測機制,以及發(fā)生網(wǎng)絡(luò)分區(qū)后如何處理。
1. 故障檢測當(dāng)MGR中個別節(jié)點與其他節(jié)點通信異常時,就會觸發(fā)故障檢測機制,經(jīng)過多數(shù)派節(jié)點投票判斷后再決定是否將其驅(qū)逐出MGR。
(資料圖)
發(fā)生故障時,只有當(dāng)多數(shù)派節(jié)點存活前提下,故障檢測機制才能工作正常,使得MGR恢復(fù)可用性;當(dāng)多數(shù)派節(jié)點本身已經(jīng)異常的時候,MGR是無法自行恢復(fù)的,需要人為介入。
MGR中,各節(jié)點間會定期交換消息,當(dāng)超過5秒(在MySQL中是固定5秒,在GreatSQL中新增選項group_replication_communication_flp_timeout?可配置)還沒收到某個節(jié)點的任何消息時,就會將這個節(jié)點標(biāo)記為可疑狀態(tài)。MGR各正常存活節(jié)點會對可疑節(jié)點每隔15秒檢測一次(在GreatSQL中,調(diào)整為每隔2秒檢測,效率更高,下面再介紹),當(dāng)確認可疑節(jié)點在超過group_replication_member_expel_timeout秒超時閾值后,再將該節(jié)點驅(qū)逐出MGR。
需要注意的是,選項group_replication_member_expel_timeout?從MySQL 8.0.21開始,默認值為5。在MySQL 8.0.21之前,默認值為0。在 <= MySQL 8.0.20 的版本中,group_replication_member_expel_timeout默認值為 0,也就是當(dāng)某節(jié)點被判定為可疑狀態(tài)后,會被立即驅(qū)逐。在MySQL 5.7中,沒有該選項,行為模式也是一樣的。
在MySQL中,MGR故障檢測是由獨立線程來完成的,該線程每隔15秒(MySQL在源碼中硬編碼定義了SUSPICION_PROCESSING_THREAD_PERIOD = 15)進行一次檢查。因此,節(jié)點發(fā)生故障時,極端情況下,可能要耗費 5(5秒沒發(fā)送消息,被判定為可疑節(jié)點) + 15(SUSPICION_PROCESSING_THREAD_PERIOD) + 5(group_replication_member_expel_timeout) = 25秒 才能驅(qū)逐該節(jié)點。最好的情況下,最快 5 + 5 = 10秒 后即可驅(qū)逐該節(jié)點。
在GreatSQL中對此進行了優(yōu)化,新增選項group_replication_communication_flp_timeout?(默認值5,最小3,最大60) 用于定義節(jié)點超過多少秒沒發(fā)消息會被判定為可疑。此外,還修改了硬編碼SUSPICION_PROCESSING_THREAD_PERIOD = 2?,也就是故障檢測線程每2秒(而非15秒)就會檢查一次。因此在GreatSQL中,最快5(group_replication_communication_flp_timeout) + 5(group_replication_member_expel_timeout) = 10秒?完成驅(qū)逐,最慢5 + 5 + 2(SUSPICION_PROCESSING_THREAD_PERIOD) = 12秒完成驅(qū)逐。
在網(wǎng)絡(luò)條件不好的情況下,建議適當(dāng)加大 group_replication_member_expel_timeout 值,避免網(wǎng)絡(luò)波動造成節(jié)點頻繁被驅(qū)逐。不過也要注意另一個風(fēng)險,見這篇文章所述:技術(shù)分享 | 為什么MGR一致性模式不推薦AFTER
存活的節(jié)點會把被驅(qū)逐的節(jié)點從成員列表中刪除,但被驅(qū)逐的節(jié)點自身可能還沒“意識”到(可能只是因為臨時短時間的網(wǎng)絡(luò)異常),在狀態(tài)恢復(fù)后,該節(jié)點會先收到一條包含該節(jié)點已被驅(qū)逐出MGR的新視圖信息,而后再重新加入MGR。被驅(qū)逐的節(jié)點會嘗試group_replication_autorejoin_tries次重新加入MGR。
選項group_replication_exit_state_action?定義了被驅(qū)逐節(jié)點之后的行為模式,默認是設(shè)置為super_read_only = ON,進入只讀模式。
2. 少數(shù)派成員失聯(lián)時當(dāng)集群中的少數(shù)派成員失聯(lián)時(Unreachable),默認不會自動退出MGR集群。這時可以設(shè)置group_replication_unreachable_majority_timeout?,當(dāng)少數(shù)派節(jié)點和多數(shù)派節(jié)點失聯(lián)超過該閾值時,少數(shù)派節(jié)點就會自動退出MGR集群。如果設(shè)置為0,則會立即退出,而不再等待。節(jié)點退出集群時,相應(yīng)的事務(wù)會被回滾,然后節(jié)點狀態(tài)變成ERROR,并執(zhí)行選項group_replication_exit_state_action?定義的后續(xù)行為模式。如果設(shè)置了group_replication_autorejoin_tries,也會再自動嘗試重新加入MGR集群。
3. 多數(shù)派成員失聯(lián)時當(dāng)多數(shù)派節(jié)點也失聯(lián)時(Unreachable),例如在一個3節(jié)點的MGR集群中,有2個節(jié)點失聯(lián)了,剩下的1個節(jié)點不能成為多數(shù)派,也就無法對新事務(wù)請求做出決策,這種情況就是發(fā)生了網(wǎng)絡(luò)分區(qū)(腦裂)。也就是一個MGR集群分裂成兩個或多個區(qū)域,也因此缺少多數(shù)派,這種情況下,MGR集群無法提供寫入服務(wù)。
此時需要人工介入,通過設(shè)置group_replication_force_members?強行指定新的成員列表。例如MGR集群由3個節(jié)點組成,其中兩個節(jié)點都意外失聯(lián)了,僅剩一個節(jié)點存活,此時就需要手動設(shè)置group_replication_force_members強行指定成員列表,也就是只有最后存活的節(jié)點。
兩個重要提醒:
使用該方法基本上是最后迫不得已的選擇,因此需要非常謹慎。若使用不當(dāng),可能會造成一個人為的腦裂場景,或者造成整個系統(tǒng)被完全阻塞。也有可能會選錯新的節(jié)點列表。 強制設(shè)定新的節(jié)點列表并解除MGR阻塞后,記得再將該選項值清空,否則無法再次執(zhí)行START GROUP_REPLICATION。
4. Xcom cache當(dāng)有節(jié)點處于可疑狀態(tài)時,在它被確定踢出MGR集群之前,事務(wù)會緩存在其他節(jié)點的Xcom cache中。這個cache對應(yīng)選項group_replication_message_cache_size。當(dāng)可疑節(jié)點短時內(nèi)又恢復(fù)后,就會先從Xcom cache中讀取記錄進行恢復(fù),然后再進行分布式恢復(fù)。因此,在網(wǎng)絡(luò)不太穩(wěn)定或并發(fā)事務(wù)較大,且物理內(nèi)存也足夠的場景里,可以適當(dāng)加大Xcom cache size;反之,在物理內(nèi)存較小,或者網(wǎng)絡(luò)較為穩(wěn)定的場景里,不應(yīng)設(shè)置太大,降低發(fā)生OOM的風(fēng)險。
在MySQL 5.7里,Xcom cache size最大值1G,且不可動態(tài)調(diào)整。從MySQL 8.0開始,可對其動態(tài)調(diào)整。在 <= MySQL 8.0.20的版本中,最小值1G。在>= MySQL 8.0.21的版本中,最小值128M。
可以執(zhí)行下面的SQL查看當(dāng)前Xcom cache消耗情況:
[root@GreatSQL]> SELECT * FROM performance_schema.memory_summary_global_by_event_name WHERE EVENT_NAME LIKE ‘memory/group_rpl/GCS_XCom::xcom_cache";
在MySQL中,是動態(tài)按需分配Xcom cache的,如果太多有空閑,就釋放;如果不夠用,再動態(tài)分配更多內(nèi)存,一次分配大概250000個cache item,很容易造成約150ms的響應(yīng)延遲。也就是說,會隨著事務(wù)多少的變化而可能頻繁產(chǎn)生響應(yīng)延遲。
在GreatSQL中,對Xcom cache采用了靜態(tài)化分配機制,即一開始就預(yù)分配約1GB內(nèi)存用于xcom cache,這可以避免前面提到的響應(yīng)延遲抖動風(fēng)險,不過“副作用”是mysqld進程所占用的內(nèi)存會比原來多,在內(nèi)存特別緊張的服務(wù)器上不太適合。
5. 網(wǎng)絡(luò)分區(qū)在MGR里,事務(wù)是需要經(jīng)過多數(shù)派節(jié)點達成一致性共識(要么都提交,要么都回滾)。同樣的,前面提到的節(jié)點間通信消息也是需要在多數(shù)派節(jié)點間達成共識。當(dāng)MGR中的多數(shù)派節(jié)點失聯(lián)時,就無法就此形成共識,也無法滿足多數(shù)派投票/仲裁要求,此時MGR將拒絕寫事務(wù)請求。這種情況,也稱為網(wǎng)絡(luò)分區(qū),及一個MGR集群分裂成兩個或多個分區(qū),彼此間相互無法連通,任何一個分區(qū)中的節(jié)點都不能達成多數(shù)派。
可能Primary節(jié)點會因為網(wǎng)絡(luò)分區(qū)時被踢出MGR集群,它在重新加回時,可能會因為本地有此前還沒來得及同步到其他節(jié)點的事務(wù),而造成本地有更多事務(wù),會報告類似下面的錯誤:
This member has more executed transactions than those present in the group. Local transactions: xx:1-300917674 > Group transactions: xx:1-300917669
此時需要人工介入處理,選擇哪個節(jié)點作為最新的Primary節(jié)點。
6. 小結(jié)本文介紹了MGR的故障檢測機制、Xcom cache,什么是網(wǎng)絡(luò)分區(qū),以及發(fā)生故障時都有什么影響,如何恢復(fù)故障等。
參考資料、文檔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)
標(biāo)簽: 故障檢測
- 環(huán)球熱議:故障檢測與網(wǎng)絡(luò)分區(qū) | 深入淺出MGR
- 全球球精選!什么是無線接入點 Access point?
- 天天熱門:Aruba推出全新AIOps解決方案 整合網(wǎng)絡(luò)和安全洞察力高效提升IT團隊效率
- 要聞:為什么 400-MHz 頻譜非常適合關(guān)鍵通信?
- 大屏游戲本ROG槍神6Plus參加秒殺 采用了ROG冰川散熱架構(gòu)2.0
- 全球新動態(tài):短鏈系統(tǒng)設(shè)計(design tiny url)
- 世界觀熱點:5G如何改變工程設(shè)計
- 天天滾動:有了 IP 地址,為什么還要用 MAC 地址?
- 酷開創(chuàng)維電腦mini至尊攜臺式電腦主機秒殺 助力便捷移動辦公
- 環(huán)球看點!5G 技術(shù)如何改變應(yīng)用程序開發(fā)?