MySQL Group Replication 技術點

mysql group replication,組複製,提供了多寫(multi-master update)的特性,加強了原有的mysql的高可用架構。mysql group replication基於mysql插件架構實現,自己就是一個mysql插件。html

提供的特性:mysql

  • 多寫,寫衝突檢測
  • 良好的擴展能力,可動態增刪節點,組成員自動管理
  • 組內高可用
  • 確保組內數據最終一致性【重要】(經過分佈式協議和分佈式recovery機制保證)

1. 架構

gr_plugin_blocks

組複製基於mysql插件架構實現,自己做爲一個mysql插件而存在。如上圖所示,藍色和綠色兩部分表示組複製架構。linux

組複製依賴mysql server主模塊(上圖灰色部分)以及mysql的複製架構,包括binary log caches、binary log applier模塊、GTID、relay log模塊、replication applier threads(組複製distributed recovery第一個階段會使用這些線程)和performance_schema(用於存儲監控組複製的狀態信息)。nginx

上圖架構中各個模塊的做用簡單介紹以下:sql

  • APIs

API層提供了組複製與上層mysql server交互的接口。上層(mysql server)會主動通知下層(組複製)根據它的狀態去作對應的動做,包括server的啓動、恢復、接受鏈接、提交事務等等。組複製根據這些接口調用作出對應的響應動做。緩存

  • Capture、Applier、Recovery

組複製中的三個核心模塊,當上層API發生調用,將根據調用類型路由到下面這三個模塊執行相應的邏輯。Capture模塊負責追蹤事務執行的上下文信息;Applier模塊負責將遠程事務加載到本地執行;Recovery模塊管理組內節點的recovery。markdown

  • Replication Protocol Logics

Replicaiton Protocol Logics模塊實現了replication協議的邏輯,邏輯功能包括: 處理衝突檢測、接收並傳播事務到組內去執行。架構

  • Group Communication System API

提供狀態機(Replication State Machine)的高層抽象API,以此分離與下層協議實現的邏輯。併發

  • Group Communication Engine

根據上層的狀態機API的抽象,這一層主要提供Paxos協議變種的核心實現。app

2. Group

mysql_group_replication_dia

一個Group由若干個mysql節點組成,每一個Group有本身的惟一命名來標識,格式爲UUID。Group內的mysql節點數據保持一致。一個組能夠動態增長和刪除節點。

組成員管理自動化。新增一個節點到一個組裏面,這個節點會自動同步自身數據跟組內其餘節點保持一致。保持同步會利用Asynchronous MySQL replication。當一個節點從一個組裏移除,將自動更改group的配置,以讓其餘節點知道這個節點的移除。

3. Multi Primary

組複製有兩種運行模式: (1) Single-Primary Mode 和 (2) Multi-Primary Mode,其中Single-Primary Mode表示一個組裏面只有一個節點用於寫,而Multi-Primary Mode下組內全部節點均可以參與寫,事務的提交能夠在組內的任意一個節點進行。

multi_primary_example

看起來Multi-Primary模式好像很屌!可是,這個模式下目前存在挺多的使用限制:

3.1 併發寫衝突

Multi-Primary模式下,對於事務的提交,須要組內全部節點進行通信,共同決定事務是否能夠提交。高併發模式下有可能出現分佈式提交衝突——不一樣的節點併發提交的事務操做了同一行數據。group replication提供的樂觀的解決方案是——先提交(時間序靠前的)的事務,可以正確被提交,然後面提交的事務,將會失敗。

multi_primary_update_conflict

官方建議,避免併發寫衝突的最好的作法是將這些會產生衝突的寫事務放到同一個節點上進行提交。

3.2 併發DDL

MySQL目前不支持事務類型的DDL,也就是說DDL操做不是一個原子操做,在Multi-Primary模式下,DDL操做併發地在多個節點執行,頗有可能產生數據不一致的狀況。所以,官方提醒,在Multi-Primary下DDL操做最好在同一個節點上執行。

若是運行在Single-Primary模式下,就沒有上面所提到的限制了。

4. Distributed Recovery

當一個新節點(被叫做joiner)加入一個group,須要從group裏面其餘節點同步狀態。這個新節點從其餘節點獲取這些落後數據,並接受新提交的事務,最終保持與group內其餘節點數據一致的這個過程,稱爲distributed recovery(DR)。DR過程分爲兩個階段:

4.1 階段1

Joiner選擇group裏面的一個節點做爲複製源(這個節點被稱做donor),基於原有的異步複製技術進行recovery。這個過程會創建從donor到joiner的replication channel,joiner不斷接收從donor端發送的binary log,apply到自身。於此同時,joiner還會監聽並緩存group裏面自從它加入以來產生的新事務。階段1結束後,將會關閉以前創建在donor和joiner之間的replication channel。

donor有可能在這個階段掛掉,此時joiner將自動選擇集羣內的其餘一個存活節點做爲donor,繼續以前的recovery。這個過程無需人爲干預。

4.2 階段2

階段2,joiner執行在階段1緩存隊列裏的新事務(直到緩存隊列爲空),而後將joiner的狀態標記爲online,表示這個節點的數據已經跟其餘節點保持一致,能夠被正常訪問。

只有online的節點才能正常接收用戶請求。

4.3 Recovering From a Point-in-time

這裏有個問題: 在階段1,joiner怎麼知道它在何時會完成全部缺失數據的recovery,單單依靠GTID機制是不夠的(依靠GTID機制只能讓joiner知道它是否少了這部分數據)。這個時候,須要有另一個機制,來表明一個時間點——這個時間點可以標識階段1的結束,也就是說在這個時間點上,joiner已經完成了從donor上全部缺失數據的recovery,接下來能夠進入階段2了。

這個機制,就是binary log view change markers,在階段1傳輸binary log流中,會帶上view change markers。那麼joiner在接受到binary log的時候,就能夠利用這些標識來判斷那個時間點的到來。

4.4 View and View Changes

在解釋view change markers以前,須要介紹view change markers關聯的概念: ViewView Changes

  • View

一個Group裏面全部節點在某個時間點上達成的配置,對外表示爲一個View。

  • View Changes

View Changes指引發Group配置發生變化的事件,好比新增節點,刪除節點。

每一個View有一個惟一標識(View Identifier)進行標識。當發生View Changes時,就會生成這樣一個惟一標識來表示這個新的View。

View changes產生的view ids做爲新節點與donor同步數據的臨界點。View change事件對應到binary log裏面是一個新binary log event的實現——view change log event。在這個view change log event裏面攜帶了view id。

假設在以前的multi-primary部署示例完成後,咱們經過登錄S2執行如下語句檢索到view change event log:

mysql > show binlog events\G;

能夠看到以下view change event log:

*************************** 9. row *************************** Log_name: binlog.000001  Pos: 742 Event_type: View_change Server_id: 1 End_log_pos: 881  Info: view_id=14817781596395401:1

4.5 Distributed Recovery Example

接下來咱們分析一個例子: 一個新節點加入一個group的過程

4.5.1 Begin: Stable Group

一開始group有3個節點S一、S二、S3,整個group處於穩定狀態

gr_recovery_1

4.5.2 View Change: Member Joins

接下來新節點S4準備加入group,引發view changes(VC4)。全部的節點都會在緩存隊列裏面緩存view change event log到隊列。同時,新節點S4會選擇group裏面的某個節點做爲donor。

全部的節點都要緩存view change event log到隊列,由於這個event log以前有可能還存在着未apply的event log,這些event log是屬於old view的。

gr_recovery_2

4.5.3 State Transfer: Catching Up

當S4選擇好donor後,就會創建與donor的replication channel,基於async replication機制從donor上同步狀態進行recovery,直到S4遇到指望的view change marker爲止。

gr_recovery_3

於此同時,S4也會不斷地接受group裏面下發的新提交事務,緩存到隊列裏面。

gr_recovery_4

4.5.4 Finish: Caught Up

當S4遇到指望的view change marker(根據view change event log 判斷)之後,與donor之間的replication channel將會被關閉,這個時候,就會從以前的緩存隊列裏面取新的事務(圖示中的T22)進行apply,直到緩存隊列爲空,而後就能夠將S4的狀態標記爲online,這就是階段2的主要動做。

注意,階段2的執行週期是不肯定的,取決於系統的負載狀況,由於在階段2期間,有可能系統不斷產生新的事務。系統的負載越高,產生的事務會越多,那麼階段2經歷的時間天然也就越長了。

gr_recovery_5

0
 
相關文章
相關標籤/搜索