MySQL Group Replication 學習筆記
作者簡介劉偉 雲和開創高級顧問
題記:group replication作為mysql官方,在5.7版本階段開發的,innodb的分布式數據庫架構,從發布開始就有很多關注,下文是我對目前為止的材料以及實驗的一些總結。
主要資料來源是官方blog:https://mysqlhighavailability.com/
group replication架構
group replication(後文簡稱GR)實現的分布式數據庫架構,底層的分布式基礎是Paxos(出於行文限製,此處不單獨交代Paxos)。通過Paxos來保證分布式數據庫係統中,事務的提交順序。
每次一個事務在一個節點提交的時候,就會發送所修改的數據到所有節點,檢查期間是否有修改衝突(比如修改了別的節點已經修改並提交成功的事務的數據),如果發現衝突,本事務回滾。如果沒有衝突,則可以直接提交成功。
對於非執行事務的遠程節點,如果事務判斷為執行成功,遠程發送過來的數據,會被保存在本地的一個relay log裏麵(注意,與常規主從同步使用的relay log不是同一組),之後由從庫的applier線程采用正常主從同步(目前已經支持LOGICAL_CLOCK並行執行)的方式執行掉對應的relay log。
這裏有一個臨界點,如果一個事務剛剛被寫入relay log,還沒有來得及執行掉,這時候有一個事務的執行涉及了相關的數據,那麼後來的這個事務在執行階段可以執行成功,但是必定會在提交階段失敗的。
使用建議
根據目前的狀況看,GR使用的時候,應該做到以下幾點以對性能優化以及減少分布式衝突。
節點分區
雖然是分布式,但並非采用純粹的隨機或者輪詢來對節點訪問,而是采用一些分區算法,保證指定的主鍵必定發生指定的實例上。
這點主要目的是避免出現事務在分布式係統中的衝突,導致不可控的事務回滾。
建議的分區算法是一致性哈希,方便節點的添加刪除,以及負載均衡。
控製單次事務操作數據量
即控製事務所涉及修改(增,刪,改)的數據,主要原因有兩點:
一是,多節點之間的衝突檢驗需要傳輸相關的數據,如果單次事務量過大,會導致單次事務的檢查時間增長,由於分布式事務的全局序列性,單個慢事務會導致全局的低速。
二是,由於最終多節點的同步,還是通過每個節點自己的relay線程來執行的,如果有大事務,會導致relay線程執行不到後麵的事務,導致事務延遲,並導致可能會產生的分布式事務回滾。
周邊功能介紹
主要組件簡介
capture 追蹤當前正在執行的事務的上下文
applier 執行遠程事務傳輸到本地的日誌到本地數據庫
recovery 負責分布式環境下的節點恢複,以及相關的數據回追,失敗處理等
失敗節點檢測
隻有認為無法連接的節點才會從集群中自動踢走。
機製如下:
不可用本身的發覺,是依賴消息通訊的超時決定的。即如果節點對另外的節點的消息發送超時,則認為遠程節點不可用。
對於正常節點,如果認為一個其他節點不可用了,首先會標記為不可用,之後與其他節點溝通,如果確認這個節點確實其他節點都認為不可用,則實際設置為不可用節點。
如果一個節點發現自生連接不到其他所有的實例(認為其他節點全部死亡),則這個節點本身之後的事務執行,就不會采用分布式算法而是退回傳統的單節點事務模式。
另外,如果同時失敗節點數過多(超過一半),為了避免腦裂,分布式算法會拒絕運行,需要人工介入恢複,這也是需要注意的一點。
節點狀態
ONLINE 節點狀態正常,可以正常執行事務
RECOVERING 正在接收種子節點的日誌
OFFLINE 節點之前注冊了,但並不屬於當前集群(可能節點已經失敗)
ERROR 恢複階段,階段1或者階段2失敗
UNREACHABLE 節點不可達,一般出現在通訊超時的情況
失敗恢複
這裏說的,主要把一個節點,加入到已有集群的過程,而非單實例的崩潰恢複。
-->階段1
第一階段,新實例選擇集群中的一個實例作為種子實例,這個種子實例會發送所有新實例到加入集群為止缺失的日誌數據到新實例,這個的執行,是通過簡單的主從同步日誌的方式做的。
執行階段1的期間,新實例還會一直持續接收當前正在活躍(實例加入集群後)的事務的日誌,補全從種子實例沒有傳輸的增量日誌。
當種子實例傳輸日誌完成之後,第一階段就完畢了。
這一階段,如果種子實例出現問題崩潰或者失敗了,新實例會自動選取實例裏麵別的實例替代。
-->階段2
這一階段,新實例合並之前的活躍事務到當前數據庫,當殘餘的事務量接近0(新事務一直在別的實例發生,隻能非常接近0而很難完全追上)的時候,實例在集群中的狀態,就會被修改為ONLINE了。
流量控製
mysql的GR,全局所有的實例都擁有所有的數據,也實際上需要運行所有的寫入流量,如果有某一個實例相對較慢,如果時間持續下去,這個節點可能出現延遲,極端情況下,可能越追越遠。
流量控製試圖做到的事情是,保障整個集群節點之間,最快的節點和最慢的節點之間的事務差距不要太大。
實際需要控製的,有兩個隊列,一個是事務提交時候的衝突檢查隊列,一個是事務實際執行的relay日誌隊列
DDL執行
DDL先天上並不支持事務化,也就是多節點執行的時候,如果有幾個節點失敗,並不會導致已經執行成功的節點回滾DDL,對於DDL的執行結果需要單獨驗證,以避免多節點表不一致。
IP白名單
這個主要是安全方麵的考慮,之允許指定來源的ip作為複製節點與集群通訊。
一些限製
使用group replication有以下一些限製。
所有涉及的數據都必須發生在InnoDB存儲引擎的表內。
所有的表必須有明確的主鍵定義。
網絡地址隻支持IPv4。
需要低延遲,高帶寬的網絡。
目前集群限製最多允許9個節點。
必須啟用binlog。
binlog 格式必須是row格式。
必須打開gtid模式。
複製相關信息必須使用表存儲。
事務寫集合(Transaction write set extraction)必須打開。(這個目前與savepoint衝突,這也是導致mysqldump無法備份GR實例的原因)
log slave updates必須打開。
binlog的checksum目前不支持。
由於事務寫集合的幹擾,無法使用savepoint。
SERIALIZABLE 隔離級別目前不支持。
對同一個對象,在集群中不同的實例上,並行地執行DDL(哪怕是相互衝突的DDL)是可行的,但會導致數據一致性等方麵的錯誤,目前階段不支持在多節點同時執行同一對象的DDL。
外鍵的級聯約束操作目前的實現並不完全支持,不推薦使用。
幾個名詞
Donor:用於節點恢複時候,傳輸曆史binlog的節點。
Group Configuration:集群裏已經配置的實例列表。
Group Membership Service:維護一致性view變更的服務,作用於節點的新增,退出,以及當前視圖的維護工作。
Joiner:將要加入到集群但狀態尚未恢複到ONLINE的新節點。
Seed:負責觸發新節點加入集群動作的實例。
View:當前集群活躍實例的列表。
本文出自數據和雲公眾號,原文鏈接
最後更新:2017-07-18 10:33:09