1. 程式人生 > 實用技巧 >Galera Cluster for MySQL 詳解(一)——基本原理

Galera Cluster for MySQL 詳解(一)——基本原理

Galera Cluster是由Codership開發的MySQL多主叢集,包含在MariaDB中,同時支援Percona xtradb、MySQL,是一個易於使用的高可用解決方案,在資料完整性、可擴充套件性及高效能方面都有可接受的表現。圖1所示為一個三節點Galera 叢集,三個MySQL例項是對等的,互為主從,這被稱為多主(multi-master)架構。當客戶端讀寫資料時,可連線任一MySQL例項。對於讀操作,從每個節點讀取到的資料都是相同的。對於寫操作,當資料寫入某一節點後,叢集會將其同步到其它節點。這種架構不共享任何資料,是一種高冗餘架構。

Galera叢集具有以下特點:

    多主架構:真正的多主多活群集,可隨時對任何節點進行讀寫。
    同步複製:叢集不同節點之間資料同步,某節點崩潰時沒有資料丟失。
    資料一致:所有節點保持相同狀態,節點之間無資料分歧。
    並行複製:重放支援多執行緒並行執行以獲得更好的效能。
    故障轉移:故障節點本身對叢集的影響非常小,某節點出現問題時無需切換操作,因此不需要使用VIP,也不會中斷服務。
    自動克隆:新增節點會自動拉取線上節點的資料,最終叢集所有節點資料一致,而不需要手動備份恢復。
    應用透明:提供透明的客戶端訪問,不需要對應用程式進行更改。

Galera叢集複製要求資料庫系統支援事務,因此僅支援MySQL的Innodb儲存引擎,並且多主模式下只能使用可重複讀隔離級別。

一、同步複製

不同於MySQL原生的主從非同步複製,Galera採用的是多主同步複製,如圖2所示。

圖2 多主同步複製

非同步複製中,主庫將資料更新傳播給從庫後立即提交事務,而不論從庫是否成功讀取或重放資料變化。這種情況下,在主庫事務提交後的短時間內,主從庫資料並不一致。同步複製時,主庫的單個更新事務需要在所有從庫上同步更新。換句話說,當主庫提交事務時,叢集中所有節點的資料保持一致。

相對於非同步複製,同步複製的優點主要體現在以下幾方面:

    資料一致:同步複製保證了整個叢集的資料一致性,無論何時在任何節點執行相同的select查詢,結果都一樣。
    高可用性:由於所有節點資料一致,單個節點崩潰不需要執行復雜耗時的故障切換,也不會造成丟失資料或停止服務。
    效能改進:同步複製允許在叢集中的所有節點上並行執行事務,從而提高讀寫效能。

當然,同步複製的缺點也顯而易見,這主要源於其實現方式。同步複製協議通常使用兩階段提交或分散式鎖協調不同節點的操作。假設叢集有n個節點,每秒處理o個操作,每個操作中包含t個事務,則每秒將在網路中產生 n*o*t 條訊息。這意味著隨著節點數量的增加,事務衝突和死鎖的概率將呈指數級增加。這也是MySQL預設使用非同步複製的主要原因。

為解決傳統同步複製的問題,現已提出多種資料庫同步複製的替代方法。除理論外,一些原型實現也顯示出了很大的希望,如以下重要改進:

    組通訊(Group Communication):定義了資料庫節點間的通訊模式,保證複製資料的一致性。
    寫集(Write-sets):將多個併發資料庫寫操作更新的資料,繫結到單個寫集訊息中,提高節點並行性。

資料庫狀態機:資料庫站點本地處理只讀事務。更新事務首先在本地的“影子拷貝(shallow copies)”上執行,然後作為讀集廣播到其它資料庫站點進行驗證並提交。

事務重排序:此操作在資料庫提交事務並將其廣播到其它站點之前重新排序事務,增加成功通過驗證的事務數。

關於寫集的概念,參見

https://wxy0327.blog.csdn.net/article/details/94614149#3.%20%E5%9F%BA%E4%BA%8EWriteSet%E7%9A%84%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%A4%8D%E5%88%B6

Galera叢集就是基於這些方法構建的。可以看到Galera複製的原理與實現與MySQL組複製有很多相似之處。為了更好地理解Galera,在深入細節之前,先將它和MySQL組複製作一類比,如下表所示。

對比項

Galera

MySQL Group Replication

組通訊系統(Group Communication System)

專有組通訊系統GComm,所有節點都必須有 ACK 訊息

基於 Paxos,只要求大多數節點有 ACK 訊息

二進位制日誌(Binlog)

不需要二進位制日誌,將二進位制行事件寫入Gcache

需要二進位制日誌

節點配置(Node Provisioning)

自動全量同步(State Snapshot Transfer,SST)與增量同步(Incremental State Transfer,IST)

沒有自動全量同步,使用非同步複製通道

全域性事務ID(GTID)

使用狀態UUID和遞增序列號

依賴GTID,叢集上的寫操作產生GTID事件

分割槽控制(Partition Handling)

分割槽節點拒絕讀寫,自動恢復並重新加入叢集

分割槽節點可讀,接受寫請求但將永久掛起,需要手工重新加入叢集

流控(Flow Control)

當一個節點慢到一個限制值,阻止所有節點寫

每個節點都有所有成員的統計資訊,獨立決定該節點寫的閾值。如果有節點慢到閾值,其它節點放慢寫速度。

DDL支援

總序隔離(Total Order Isolation,TOI),DDL執行期間,所有寫入都將被阻止

DDL 並不會阻塞寫,僅建議在單主模式下使用(因為 DDL 並沒有衝突檢測)

二、Galera複製架構

同步複製系統中的節點將通過單個事務更新副本,從而與所有其它節點同步。這意味著當事務提交時,所有節點都將具有相同的值。此過程通過組通訊使用寫集複製進行。

Galera叢集的內部架構包含四個元件,如圖3所示:

    資料庫管理系統(DBMS):在單個節點上執行的資料庫伺服器。Galera群集可以使用MySQL、Mariadb或Percona xtradb。
    wsrep api:Galera與資料庫伺服器的介面,為上層提供了豐富的狀態資訊和回撥函式。wsrep api由wsrep hooks、dlopen函式兩部分組成。wsrep hooks鉤子程式用於與資料庫伺服器引擎整合。dlopen函式使Galera外掛中的複製程式對wsrep hooks可用。
    Galera複製外掛:實現寫集複製功能的核心模組。
    組通訊外掛:Galera叢集的組通訊系統(Group Communication System,GCS),如GComm。

如下圖:

圖3 Replication API

1. wsrep api

wsrep api是資料庫的通用複製外掛介面,定義了一組應用程式回撥和複製外掛呼叫函式。wsrep api將資料庫中的資料改變視為一種狀態變化,當客戶端修改資料庫內容時,其狀態將更改。wsrep api將資料庫狀態更改表示為一系列事務。叢集中的所有節點始終具有相同狀態,它們通過以相同的順序複製和應用狀態更改來相互同步。從更技術角度看,Galera叢集使用以下方式處理狀態更改:

    一個節點的資料庫中發生狀態更改。
    wsrep鉤子將更改轉換為寫集。
    dlopen函式連線wsrep鉤子與Galera複製外掛。
    Galera複製外掛處理寫集驗證,並將更改複製到叢集中的其它節點。

2. 全域性事務ID(global transaction id,GTID)

在MySQL社群中,GTID的概念並不新鮮,MySQL中的GTID由Master生成,是用於標記唯一事務並通過ID定位binlog位置的一種手段,從而有效解決了級聯複製等場景中的各種問題。

對Galera Cluster而言,複製不基於binlog,而是通過Galera複製外掛來保障。Galera的GTID同樣也標記事務唯一性,wsrep api使用GTID識別狀態更改。Galera的GTID格式如下:

45eec521-2f34-11e0-0800-2a36050b826b:94530586304

GTID由兩部分組成:

    狀態UUID:表示當前狀態的唯一ID,可以簡單認為是叢集的一個唯一識別符號。
    順序號:一個64位有符號整數,表示事務在Galera Cluster所有節點中的序號。

3. Galera複製外掛

Galera複製外掛實現wsrep api,作為wsrep provider執行。Galera複製外掛由以下元件構成:

    驗證層:該層準備寫集,並檢測本機事務,以及從其它節點同步來的事務是否可以提交。
    複製層:該層的工作包含組通訊和並行複製兩方面。組通訊負責與其它節點同步寫集,併為事務分配全域性唯一的GTID。並行複製實現Galera事務樂觀並行控制。

4. 組通訊外掛

組通訊框架為各種gcomm系統提供了一個外掛體系結構。Galera叢集建立在專有的組通訊系統層之上,實現虛擬同步。所謂虛擬同步,簡單說是指一個事務在一個節點上執行成功後,保證它在其它節點也一定會被成功執行,但並不能保證實時同步。為了解決實時性問題,Galera叢集實現了自己的執行時可配置的時態流控。
組通訊框架還使用GTID提供來自多個源的訊息總序(Total Order)。在傳輸層上,Galera叢集是一個對稱的無向圖,所有節點都通過TCP相互連線。預設情況下,TCP用於訊息複製和群整合員資格服務,但也可以使用udp多播在LAN中進行復制。

三、Galera複製工作原理

Galera複製是一種基於驗證的複製,以這兩篇論文為理論基礎:Don’t be lazy, be consistent和 Database State Machine Approach

基於驗證的複製使用組通訊和事務排序技術實現同步複製。它通過廣播併發事務之間建立的全域性總序來協調事務提交。簡單說就是事務必須以相同的順序應用於所有例項。事務在本節點樂觀執行,然後在提交時執行一個驗證過程以保證全域性資料一致性。所謂樂觀執行是指,事務在一個節點提交時,被認為與其它節點上的事務沒有衝突,首先在本地執行,然後再發送到所有節點做衝突檢測,無衝突時在所有節點提交,否則在所有節點回滾。Galera複製原理如圖4所示:

圖4 基於驗證的複製

當客戶端發出commit命令時,在實際提交之前,對資料庫所做的更改都將被收集到一個寫集中,寫集中包含事務資訊和所更改行的主鍵。然後,資料庫將此寫集傳送到所有其它節點。節點用寫集中的主鍵與當前節點中未完成事務的所有寫集(不僅包括當前節點其它事務產生的寫集,還包括其它節點傳送過來的寫集)的主鍵相比較,確定節點是否可以提交事務。同時滿足以下三個條件則驗證失敗(存在衝突):

    兩個事務來源於不同節點。
    兩個事務包含相同的主鍵。
    老事務對新事務不可見,即老事務未提交完成。新老事務的劃定依賴於全域性事務總序,即GTID。

驗證失敗後,節點將刪除寫集,叢集將回滾原始事務。對於所有的節點都是如此,每個節點單獨進行驗證。因為所有節點都以相同的順序接收事務,它們對事務的結果都會做出相同的決定,要麼全成功,要麼都失敗。成功後自然就提交了,所有的節點又會重新達到資料一致的狀態。節點之間不交換“是否衝突”的資訊,各個節點獨立非同步處理事務。由此可見,Galera本身的資料也不是嚴格同步的,很明顯在每個節點上的驗證是非同步的,這也就是前面提到的“虛擬同步”。

最後,啟動事務的節點可以通知客戶端應用程式是否提交了事務。

四、狀態轉移

當一個新節點加入叢集時,資料將從叢集複製到這個節點,這是一個全自動的過程,Galera將此稱為狀態轉移。前面介紹Galera架構時曾提到,wsrep api將叢集中的資料改變視為狀態改變,因此這裡將資料同步稱作狀態轉移也就不足為怪了。Galera叢集中有兩種狀態轉移方法:

    狀態快照傳輸(State Snapshot Transfers,SST),也就是通常所說的全量資料同步。
    增量狀態轉移(Incremental State Transfers,IST),指增量資料同步。

當有新節點加入時,叢集會選擇出一個捐獻者(Donor)節點為新節點提供資料,這點與MySQL組複製類似。

1. 狀態快照傳輸

新節點加入叢集時會啟動狀態快照傳輸(SST),將其資料與叢集同步。Galera支援rsync、rsync_-wan、xtrabackup、mysqldump四種狀態快照傳輸方法,由系統變數wsrep_sst_method指定,預設為rsync。

rsync、rsync_-wan、xtrabackup三種方法是物理備份,將資料檔案直接從捐獻者伺服器複製到新節點伺服器,並在傳輸後初始化接收伺服器,其中xtrabackup方式可實現捐贈者無阻塞資料同步。這些方法比mysqldump快很多。

mysqldump方法是邏輯備份,要求使用者手動初始化接收伺服器,並在傳輸之前準備好接受連線。這是一種阻塞方法,在傳輸期間,捐贈節點變為只讀。mysqldump是狀態快照傳輸最慢的方法,不建議在生產環境使用。

2. 增量狀態轉移

增量狀態轉移(IST)只向新節點發送它所缺失的事務。使用IST需要滿足兩個先決條件:

    新加入節點的狀態UUID與叢集中的節點一致。
    新加入節點所缺失的寫集在捐助者的寫集快取中存在。這點很好理解,類比MySQL的binlog,如果所需的binlog檔案缺失,是無法做增量備份恢復的。

滿足這些條件時,捐助節點單獨傳輸缺失的事務,並按順序重放它們,直到新節點趕上叢集。例如,假設叢集中有一個節點落後於叢集。此節點攜帶的節點狀態如下:

5a76ef62-30ec-11e1-0800-dba504cf2aab:197222

同時,叢集上的捐助節點狀態為:

5a76ef62-30ec-11e1-0800-dba504cf2aab:201913

叢集上的捐助節點從加入節點接收狀態轉移請求。它檢查自身寫集快取中的序列號197223。如果該序號在寫集快取中不可用,則會啟動SST。否則捐助節點將從197223到201913的提交事務傳送到新加入節點。增量狀態傳輸的優點是可以顯著加快節點合併到叢集的速度。另外,這個過程對捐贈者來說是非阻塞的。

增量狀態傳輸最重要的引數是捐助節點上的gcache.size,它控制分配多少系統記憶體用於快取寫集。可用空間越大,可以儲存的寫集越多。可以儲存的寫集越多,通過增量狀態傳輸可以彌合的事務間隙就越大。另一方面,如果寫集快取遠大於資料庫大小,則增量狀態傳輸開始時的效率低於傳送狀態快照。

3. 寫集快取(gcache)

Galera群集將寫集儲存在一個稱為gcache的特殊快取中。gcache使用三種類型的儲存:

    1.永久記憶體儲存(Permanent In-Memory Store):寫集使用作業系統的預設記憶體分配器進行分配,永久儲存於物理記憶體中。gcache.keep_pages_size引數指定保留的記憶體頁總大小,預設值為0。由於硬體的限制,預設情況下是禁用的。
    2.永久環緩衝區檔案(Permanent Ring-Buffer File):寫集在快取初始化期間預分配到磁碟,生成一個記憶體對映檔案,用作寫集儲存。檔案目錄和檔名分別由gcache.dir和gcache.name引數指定。檔案大小由gcache.size引數指定,預設值為128MB。
    3.按需頁儲存(On-Demand Page Store):根據需要在執行時將寫集分配給記憶體對映頁檔案。大小由gcache.page_size引數指定,預設值為128M,可隨寫集自動變大。頁面儲存的大小受可用磁碟空間的限制。預設情況下,Galera會在不使用時刪除頁面檔案,使用者可以設定要保留的頁面檔案總大小(gcache.size)。當所有其它儲存被禁用時,磁碟上至少保留一個頁面的檔案。

Galera叢集使用一種分配演算法,嘗試按上述順序儲存寫集。也就是說,它首先嚐試使用永久記憶體儲存,如果沒有足夠的空間用於寫入集,它將嘗試儲存到永久環緩衝區檔案。除非寫入集大於可用磁碟空間,否則頁面儲存始終成功。

注意,如果gcache.recover引數設定為yes,則在啟動時將嘗試恢復gcache,以便該節點可以繼續向其它節點提供IST服務。如果設定為no(預設),gcache將在啟動時失效,節點將只能為SST提供服務。

五、流控

Galera叢集內部使用一種稱為流控的反饋機制來管理複製過程。流控允許節點根據需要暫停和恢復複製,這可以有效防止任一節點在應用事務時落後其它節點太多。

1. 流控原理

從Galera叢集同步複製(虛擬同步)原理可知,事務的應用和提交在各個節點上非同步發生。節點從叢集接收但尚未應用和提交的事務將保留在接收佇列中。由於不同節點之間執行事務的速度不一樣,慢節點的接收佇列會越積越長。當接收佇列達到一定大小時,節點觸發流控,作用就是協調各個節點,保證所有節點執行事務的速度大於佇列增長速度。流控的實現原理很簡單:整個Galera叢集中,同時只有一個節點可以廣播訊息,每個節點都會獲得廣播訊息的機會(獲得機會後也可以不廣播)。當慢節點的接收佇列超過一定長度後,它會廣播一個FC_PAUSE訊息,所有節點收到訊息後都會暫緩廣播訊息,直到該慢節點的接收佇列長度減小到一定長度後再恢復複製。

流控相關引數如下:

    1.gcs.fc_limit:接收佇列中積壓事務的數量超過該值時,流控被觸發,預設值為16。對於Master-Slave模式(只在一個節點寫)的Galera叢集,可以配置一個較大的值,防止主從複製延遲。對啟動多寫的Galera叢集,較小的值比較合適,因為較大的接收佇列長度意味著更多衝突。
    2.gcs.fc_factor:當接收佇列長度開始小於 gcs.fc_factor * gcs.fc_limit 時恢復複製,預設值為1。
    3.gcs.fc_master_slave:Galera叢集是否為Master-Slave模式,預設為no。

2. 理解節點狀態

一個節點在Galera叢集中可能經歷的節點狀態有Open、Primary、Joiner、Joined、Synced、Donor。可以通過wsrep_local_state和wsrep_local_state_comment系統變數檢視節點的當前狀態。節點狀態更改如圖5所示:

圖5 節點狀態轉換

說明:

    1.節點啟動並建立到主元件( Primary Component,PC)的連線。由於網路問題群集可能被拆分為多個部分,為避免資料差異或腦裂,此時只能有一部分可以修改資料,這部分稱為主元件。
    2.當節點成功執行狀態傳輸請求時,它將開始快取寫集。
    3.節點接收狀態快照傳輸(SST)。它將擁有所有叢集資料,並開始應用快取的寫集。
    4.節點完成對群集的追趕。節點將mysql狀態變數wsrep_ready設定為值1,現在允許該節點處理事務。
    5.節點接收狀態傳輸請求,成為捐贈者。節點快取它無法應用的所有寫集。
    6.節點完成對新加入節點的狀態傳輸。

3. 節點狀態與流控

Galera叢集根據節點狀態實現多種形式的流控以保證資料一致性。有四種主要流控型別:

    1.無流控(No Flow Control):當節點處於Open或Primary狀態時,此流控型別生效。此時節點還不被視為叢集的一部分,不允許這些節點複製、應用或快取任何寫集。
    2.寫集快取(Write-set Caching):當節點處於Joiner和Donor狀態時,此流控型別生效。節點在此狀態下不能應用任何寫集,必須快取它們以備以後使用。
    3.趕上(Catching Up):此流控型別在節點處於Joined狀態時生效。處於此狀態的節點可以應用寫集。這裡的流控確保節點最終能夠追趕上叢集。由於應用寫集通常比處理事務快幾倍,處於這種狀態的節點幾乎不會影響叢集效能。
    4.叢集同步(Cluster Sync):此流控型別在節點處於Synced狀態時生效。當節點進入此狀態時,流控將嘗試將接收佇列保持最小。

六、單節點故障與恢復

當一個節點因為硬體、軟體、網路等諸多原因與叢集失去聯絡時,都被概括為節點故障。從叢集的角度看,主元件看不到出問題的節點,它將會認為該節點失敗。從故障節點本身的角度來看,假設它沒有崩潰,那麼唯一的跡象是它失去了與主元件的連線。可以通過輪詢wsrep_local_state狀態變數監控Galera群集節點的狀態,值及其含義見上節流控中的描述。

叢集檢查從節點最後一次接收到資料包的時間確定該節點是否連線到叢集,檢查的頻率由evs.inactive_check_period引數指定,預設值為每隔0.5秒檢查一次。在檢查期間,如果群集發現自上次從節點接收網路資料包以來的時間大於evs.keepalive_period引數的值(預設值為1秒),則它將開始發出心跳訊號。如果叢集在evs.suspect_timeout引數(預設值為5秒)期間沒有繼續從節點接收到網路資料包,則該節點被宣告為suspect,表示懷疑該節點已下線。一旦主元件的所有成員都將該節點視為可疑節點,它就被宣告為inactive,即節點失敗。如果在大於evs.inactive_timeout(預設值為15秒)的時間內未從節點接收到訊息,則無論意見是否一致,都會宣告該節點失敗。在所有成員同意其成員資格之前,失敗節點將保持非操作狀態。如果成員無法就節點的活躍性達成一致,說明網路對於叢集操作來說太不穩定。

這些選項值之間的關係為:

evs.inactive_check_period <= evs.keepalive_period <= evs.suspect_timeout <=    evs.inactive_timeout

需要注意,如果網路過於繁忙,以至於無法按時傳送訊息或心跳訊號無響應,也可能被宣佈為節點失敗,這可以防止叢集其餘部分的操作被鎖。如果不希望這樣處理,可以增加超時引數。如果用CAP原則來衡量,Galera叢集強調的是資料一致性(Consistency),這就導致了叢集需要在可用性(Availability)和分割槽容忍性(Partition tolerance)之間進行權衡。也就是說,當使用的網路不穩定時,低evs.suspect_timeout和evs.inactive_timeout值可能會導致錯誤的節點故障檢測結果,而這些引數的較高值可能會導致在實際節點故障的情況下更長的發現時間。

叢集中的一個節點出現故障不會影響其它節點繼續正常工作,單節點故障不會丟失任何資料。失敗節點的恢復是自動的。當失敗節點重新聯機時,它會自動與其它節點同步資料,之後才允許它重新回到叢集中。如果重新同步過程中狀態快照傳輸(SST)失敗,會導致接收節點不可用,因為接收節點在檢測到狀態傳輸故障時將中止。這種情況下若使用的是mysqldump方式的SST,需要手動還原

七、仲裁

除了單節點故障外,群集還可能由於網路故障而拆分為多個部分。每部分內的節點相互連線,但各部分之間的節點失去連線,這被稱為網路分裂(network partitioning)。此情況下只有一部分可以繼續修改資料庫狀態,以避免資料差異,這一部分即為主元件。正常情況下主元件就是整個叢集。當發生網路分裂時,Galera叢集呼叫一個仲裁演算法選擇一部分作為主元件,保證叢集中只有一個主元件。

1. 加權法定票數(Weighted Quorum)

叢集中的當前節點數量定義了當前叢集的大小,群集大小決定達到仲裁所需的票數。Galera叢集在節點不響應並且被懷疑不再是叢集的一部分時進行仲裁投票。可以使用evs.suspect_timeout引數微調此無響應的超時時間,預設為5秒。

發生網路分裂時,斷開連線的兩側都有活動節點。主元件要求獲得仲裁的多數票,因此具有較多存活節點的部分將成為主元件,而另一部分將進入非主狀態並開始嘗試與主元件連線,如圖6所示。

圖6 仲裁新主元件

仲裁要求多數,這意味著不能在雙節點群集中進行自動故障轉移,因為一個節點的故障會導致另一節點自動進入非主狀態。而具有偶數個節點的叢集則有腦裂風險。如果在網路分裂導致節點的數量正好分成兩半,則兩個分割槽都不能成為主元件,並且都進入非主狀態,如圖7所示。要啟用Galera叢集自動故障切換,至少需要使用三個節點。

圖7 腦裂

2. 腦裂(Split-Brain)

導致資料庫節點彼此獨立執行的叢集故障稱為“腦裂”。這種情況可能導致資料不一致,並且無法修復,例如當兩個資料庫節點獨立更新同一表上的同一行時。與任何基於仲裁的系統一樣,當仲裁演算法無法選擇主元件時,Galera叢集會受到腦裂影響。

Galera設計為避免進入分裂腦狀態,如果失敗導致將叢集分割為兩個大小相等的部分,則兩部分都不會成為主元件。在節點數為偶數的叢集中,為把腦裂風險降到最低,可以人為分割槽將一部分始終劃分為叢集主元件,如:

4 node cluster -> 3 (Primary) + 1 (Non-primary)
6 node cluster -> 4 (Primary) + 2 (Non-primary)
6 node cluster -> 5 (Primary) + 1 (Non-primary)

以上分割槽示例中,任何中斷或失敗都很難導致節點完全分成兩半。

3. 法定票數計算

Galera群集支援加權仲裁,其中每個節點可以被分配0到255範圍內的權重參與計算。法定票數計算公式為:

其中:

    pi:最後可見的主元件的成員;
    li:已知正常離開叢集的成員;
    mi:當前元件成員;
    wi:成員權重。

這個公式的含義是:當且僅當當前節點權重總和大於最後一個主元件節點權重和減去正常離開叢集節點權重和的一半時,才會被選為新的主元件。

訊息傳遞時帶有權重資訊。預設的節點權重為1,此時公式被轉換為單純的節點計數比較。通過設定pc.weight引數,可以在執行時更改節點權重,例如:

set global wsrep_provider_options="pc.weight=3";

4. 加權仲裁示例

在瞭解了加權仲裁的工作原理後,下面是一些部署模式的示例。

(1)三個節點的加權仲裁

三個節點配置仲裁權重如下:

node1: pc.weight = 2
node2: pc.weight = 1
node3: pc.weight = 0

此時如果node2和node3失效,node1會成為主元件,而如果node1失效,node2和node3都將成為非主元件。

(2)一主一從方案的加權仲裁

主、從節點配置仲裁權重如下:

node1: pc.weight = 1
node2: pc.weight = 0

如果主節點失效,node2將成為非主元件,如果node2失效,node1將繼續作為主元件。

(3)一主多從方案的加權仲裁
為具有多個從節點的主從方案配置仲裁權重:

    node1: pc.weight = 1
    node2: pc.weight = 0
    node3: pc.weight = 0
    ...
    noden: pc.weight = 0

如果node1失效,所有剩餘的節點都將作為非主元件,如果任何其它節點失效,則保留主元件。在網路分裂的情況下,node1始終作為主元件。(4)主站點和從站點方案的加權仲裁
為主站點和從站點配置仲裁權重:

    Primary Site:
      node1: pc.weight = 2
      node2: pc.weight = 2
     
    Secondary Site:
      node3: pc.weight = 1
      node4: pc.weight = 1

這種模式下,一些節點位於主站點,而其它節點位於從站點。如果從站點關閉或站點之間的網路連線丟失,則主站點上的節點仍然是主元件。此外,node1或node2崩潰不會讓其它剩餘節點成為非主元件。

參考:https://wxy0327.blog.csdn.net/article/details/102522268