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

目錄

一、同步複製

二、Galera複製架構

1. wsrep api

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

3. Galera複製插件

4. 組通信插件

三、Galera複製工作原理

四、狀態轉移

1. 狀態快照傳輸

2. 增量狀態轉移

3. 寫集緩存(gcache)

五、流控

1. 流控原理

2. 理解節點狀態

3. 節點狀態與流控

六、單節點故障與恢復

七、仲裁

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

2. 裂腦(Split-Brain)

3. 法定票數計算

4. 加權仲裁示例

參考:


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

圖1 三節點Galera集羣

 

        Galera集羣具有以下特點:

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

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

一、同步複製

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

圖2 多主同步複製

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

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

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

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

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

  • 組通信(Group Communication):定義了數據庫節點間的通信模式,保證複製數據的一致性。
  • 寫集(Write-sets):將多個併發數據庫寫操作更新的數據,綁定到單個寫集消息中,提高節點並行性。關於寫集的概念,參見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
  • 數據庫狀態機:數據庫站點本地處理只讀事務。更新事務首先在本地的“影子拷貝(shallow copies)”上執行,然後作爲讀集廣播到其它數據庫站點進行驗證並提交。
  • 事務重排序:此操作在數據庫提交事務並將其廣播到其它站點之前重新排序事務,增加成功通過驗證的事務數。

        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集羣使用以下方式處理狀態更改:

  1. 一個節點的數據庫中發生狀態更改。
  2. wsrep鉤子將更改轉換爲寫集。
  3. dlopen函數連接wsrep鉤子與Galera複製插件。
  4. 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使用三種類型的存儲:

  • 永久內存存儲(Permanent In-Memory Store):寫集使用操作系統的默認內存分配器進行分配,永久存儲於物理內存中。gcache.keep_pages_size參數指定保留的內存頁總大小,缺省值爲0。由於硬件的限制,默認情況下是禁用的。
  • 永久環緩衝區文件(Permanent Ring-Buffer File):寫集在緩存初始化期間預分配到磁盤,生成一個內存映射文件,用作寫集存儲。文件目錄和文件名分別由gcache.dir和gcache.name參數指定。文件大小由gcache.size參數指定,缺省值爲128MB。
  • 按需頁存儲(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消息,所有節點收到消息後都會暫緩廣播消息,直到該慢節點的接收隊列長度減小到一定長度後再恢復複製。

        流控相關參數如下:

  • gcs.fc_limit:接收隊列中積壓事務的數量超過該值時,流控被觸發,缺省值爲16。對於Master-Slave模式(只在一個節點寫)的Galera集羣,可以配置一個較大的值,防止主從複製延遲。對啓動多寫的Galera集羣,較小的值比較合適,因爲較大的接收隊列長度意味着更多衝突。
  • gcs.fc_factor:當接收隊列長度開始小於 gcs.fc_factor * gcs.fc_limit 時恢復複製,缺省值爲1。
  • 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集羣根據節點狀態實現多種形式的流控以保證數據一致性。有四種主要流控類型:

  • 無流控(No Flow Control):當節點處於Open或Primary狀態時,此流控類型生效。此時節點還不被視爲集羣的一部分,不允許這些節點複製、應用或緩存任何寫集。
  • 寫集緩存(Write-set Caching):當節點處於Joiner和Donor狀態時,此流控類型生效。節點在此狀態下不能應用任何寫集,必須緩存它們以備以後使用。
  • 趕上(Catching Up):此流控類型在節點處於Joined狀態時生效。處於此狀態的節點可以應用寫集。這裏的流控確保節點最終能夠追趕上集羣。由於應用寫集通常比處理事務快幾倍,處於這種狀態的節點幾乎不會影響集羣性能。
  • 集羣同步(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崩潰不會讓其它剩餘節點成爲非主組件。

參考:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章