天天看點

MySQL Group Replication 學習筆記—group replication 小結group replication 小結

group replication作為mysql官方,在5.7版本階段開發的,innodb的分布式資料庫架構,從釋出開始就有很多關注,下文是我對目前為止的材料以及實驗的一些總結。

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的執行結果需要單獨驗證,以避免多節點表不一緻。

這個主要是安全方面的考慮,之允許指定來源的ip作為複制節點與叢集通訊。

一些雜七雜八的限制。

所有涉及的資料都必須發生在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:目前叢集活躍執行個體的清單。

<b>本文來自雲栖社群合作夥伴“dbgeek”</b>