RDS 5.7三節點企業版時代的數據一致性解決方案

  上篇咱們看到了在MySQL主備模式下,咱們在數據一致性上作了很多事情,但解決方案都有必定的侷限性,適合部分場景或者解決不完全的問題。隨着以Google Spanner以及Amazon Aruora 爲表明的NewSQL的快速發展,爲數據庫的數據一致性給出了與以往不一樣的思路: 基於分佈式一致性協議!咱們也實現了一個獨立的分佈式協議庫X-Paxos,並將這個特性繼承到了RDS 5.7三節點企業版中。(RDS 5.7三節點在7月15日即將開始公測,敬請關注!)算法

一.分佈式一致性協議

  說到一致性協議,咱們一般就會講到複製狀態機。通常狀況下,咱們會用複製狀態機加上一致性協議算法來解決分佈式系統中的高可用和容錯。許多分佈式系統,都是採用複製狀都是採用複製狀態機來進行副本之間的數據同步,好比HDFS,Chubby和Zookeeper等。

  所謂複製狀態機,就是在分佈式系統的每個實例副本中,都維持一個持久化的日誌,而後用必定的一致性協議算法,保證每一個實例的這個log都保持徹底一致,實例內部的狀態機按照日誌的順序回放日誌中的每一條命令,這樣客戶端來讀取數據時時,在每一個副本上都能讀到同樣的數據。複製狀態機的核心就是圖中的Consensus模塊,也就是咱們要討論的Paxos,Raft等一致性協議算法(準確的說,Paxos並不指代一個協議,而是一類協議的統稱,比較常見的paxos類協議有Basic-Paxos 和Multi-Paxos)數據庫

1.Basic-Paxos

  Basic-Paxos是Lamport最早提出的分佈式一致性算法。要理解Paxos,只要記住一點就行了,Paxos只能爲一個值造成共識,一旦Propose被肯定,以後值永遠不會變,也就是說整個Paxos Group只會接受一個提案(或者說接受多個提案,但這些提案的值都同樣)。
  Paxos協議中有三個角色,Proposer和Acceptor和Learner角色(Leaner只是學習Proposer的結果,暫時不討論該角色)。Paxos容許多個Proposer同時提案。Proposer要提出一個值讓全部Acceptor達成一個共識,達成一個共識分爲2個階段:Prepare階段和Accept階段。網絡

Prepare階段多線程

  Proposer會給出一個ProposeID N(注意,此階段Proposer不會把值傳給Acceptor)給每一個Acceptor,若是某個Acceptor發現本身歷來沒有接收過大於等於N的Propose,則會回覆Proposer,同時承諾再也不接收ProposeID小於等於N的提議的Prepare。若是這個Acceptor已經承諾過比N更大的propose,則不會回覆Proposer。(若是Acceptor以前已經Accept了(完成了第二個階段)一個小於N的Propose,則會把這個Propose的值返回給Proposer,不然會返回一個null值。當Proposer收到大於半數的Acceptor的回覆後,就能夠開始第二階段。)架構

Accept階段併發

  這個階段Propose可以提出的值是受限的,只有它收到的回覆中不含有以前Propose的值,他才能提出一個新的value,不然只能用回覆中Propose最大的值做爲提議的值。Proposer用這個值和ProposeID N對每一個Acceptor發起Accept請求。也就是說就算Proposer以前已經獲得過acceptor的承諾,可是在accept發起以前,Acceptor可能給了proposeID更高的Propose承諾,致使accept失敗。也就是說因爲有多個Proposer的存在,雖然第一階段成功,第二階段仍然可能會被拒絕掉。框架

2.Multi-Paxos

前面講的Paxos還過於理論,沒法直接用到複製狀態機中,總的來講,有如下幾個緣由異步

1).Paxos只能肯定一個值,沒法用作Log的連續複製
2).因爲有多個Proposer,可能會出現活鎖
3).提案的最終結果可能只有部分Acceptor知曉,沒法達到複製狀態機每一個instance 的log徹底一致。

  Multi-Paxos,就是爲了解決上述三個問題,使Paxos協議可以實際使用在狀態機中。解決第一個問題其實很簡單:爲Log Entry每一個index的值都用一個獨立的Paxos instance。解決第二個問題也很簡單,讓一個Paxos group中不要有多個Proposer,在寫入時先用Paxos協議選出一個leader(如我上面的例子),以後只由這個leader寫入,就能夠避免活鎖問題。而且,有了單一的leader以後,咱們還能夠省略掉大部分的prepare過程。只須要在leader當選後作一次prepare,全部Acceptor都沒有接受過其餘Leader的prepare請求,那每次寫入,均可以直接進行Accept,除非有Acceptor拒絕,這說明有新的leader在寫入。爲了解決第三個問題,Multi-Paxos給每一個Server引入了一個firstUnchosenIndex,讓leader可以向每一個Acceptor同步被選中的值。解決這些問題以後Paxos就能夠用於實際工程了。
  Paxos到目前已經有了不少的補充和變種,實際上,ZAB也好,Raft也好,均可以看作是對Paxos的修改和變種。關於Paxos,還有一句流傳甚廣的話,「世上只有一種一致性算法,那就是Paxos」。
3.Raft
  Raft是斯坦福大學在2014年提出的一種新的一致性協議,協議的內容,網上材料太多,不作過多闡述,這裏僅和Paxos作一下比較:分佈式

1).Raft則將Multi-Paxos的功能作了模塊劃分,並對每一個模塊作了詳細的闡述和理論證實:Leader Election、Log Replication、Commit Index Advance、Crash Recovery、Membership Change 等。
2).Multi-Paxos和Raft,最本質的區別在於,是否容許日誌空洞。Raft必須連續,不容許空洞。Multi-Paxos容許日誌空洞存在

二.X-Paxos

  X-Paxos是一個從阿里業務場景出發、基於分佈式一致性協議的實現(嚴格意義來講,X-Paxos的實現同時參考了經典的multi-Paxos和Raft協議),服務於RDS 5.7三節點企業版。同時X-Paxos是一個公共庫,能夠應用在更多的系統。下面詳細講一下X-Paxos

X-Paxos的總體架構如上圖所示,主要可分爲網絡層、服務層、算法模塊、日誌模塊4個部分。性能

1.網絡層

  網絡層基於阿里內部很是成熟的網絡庫libeasy實現。libeasy的異步框架和線程池很是契合咱們的總體異步化設計,同時咱們對libeasy的重連等邏輯進行了修改,以適應分佈式協議的需求。

2.服務層

  服務層是驅動整個Paxos運行的基礎,爲Paxos提供了事件驅動,定時回調等核心的運行功能,每個Paxos實現都有一個與之緊密相關的驅動層,驅動層的架構與性能和穩定性密切相關。X-Paxos的服務層是一個基於C++11特性實現的多線程異步框架。常見的狀態機/回調模型存在開發效率較低,可讀性差等問題,一直被開發者所詬病;而協程又因其單線程的瓶頸,而使其應用場景受到限制。C++11之後的新版本提供了完美轉發(argument forwarding)、可變模板參數(variadic templates)等特性,藉助C++11的這個特性,咱們實現了一種全新的異步調用模型。

3.算法模塊

  X-Paxos當前的算法基於強leadership的multi-paxos[3]實現,大量理論和實踐已經證實了強leadership的multi-paxos,性能好於multi-paxos/basic paxos,當前成熟的基於Paxos的系統,都採用了這種方式。
算法模塊的基礎功能部分本文再也不重複,感興趣的同窗能夠參考相關論文。在基礎算法的基礎上,結合阿里業務的場景以及高性能和生態的需求,X-Paxos作了不少的創新性的功能和性能的優化,使其相對於基礎的multi-paxos,功能變的更加豐富,性能也有明顯的提高。下一章中,將對這些優化進行詳細的介

4.日誌模塊

  日誌模塊本是算法模塊的一部分,可是出於對極致性能要求的考慮,咱們把日誌模塊獨立出來,並實現了一個默認的高性能的日誌模塊;有極致性能以及成本需求的用戶,能夠結合已有的日誌系統,對接日誌模塊接口,以獲取更高的性能和更低的成本。這也是X-Paxos做爲高性能獨立庫特有的優點,後面也會對這塊進行詳細介紹。

三. RDS 5.7三節點企業版的數據一致性解決方案

  RDS 5.7三節點企業版是第一個接入X-Paxos生態的重要產品,它是一個自封閉、高可靠、強一致、高性能的數據庫系統,能夠憑藉內核自己完全解決數據質量的問題,無需外部介入。同時RDS 5.7三節點企業版也是基於MySQL生態,兼容最新版本的MySQL 5.7,對於MySQL的用戶來講,能夠無縫遷移到RDS 5.7三節點企業版。

1.總體架構

  先來看一下RDS 5.7三節點企業版的基本架構

  上圖展現的是一個部署三個實例的RDS 5.7三節點企業版集羣。RDS 5.7三節點企業版是一個單點寫入,多點可讀的集羣系統。在同一時刻,整個集羣中至多會有一個Leader節點來承擔數據寫入的任務。相比多點寫入,單點寫入不須要處理數據集衝突的問題,能夠達到更好的性能與吞吐率。
  RDS 5.7三節點企業版的每一個實例都是一個單進程的系統,X-Paxos被深度整合到了數據庫內核之中,替換了原有的複製模塊。集羣節點之間的增量數據同步徹底是經過X-Paxos來自驅動,再也不須要外部手動指定複製位點。 RDS 5.7三節點企業版爲了追求最高的性能,選擇了本身實現Consensus日誌這種接入X-Paxos的方式,在MySQL Binlog的基礎上實現了一系列X-Paxos日誌接口,賦予X-Paxos操縱Binlog的能力。
  用戶在訪問RDS 5.7三節點企業版時能夠直接使用MySQL原生的客戶端進行訪問,完美兼容MySQL生態的周邊系統,包括中間件、備份恢復、DTS等等。

2.複製流程


  RDS 5.7三節點企業版的複製流程是基於X-Paxos驅動Consensus日誌進行復制,Leader節點在事務prepare階段會將事務產生的日誌收集起來,傳遞給X-Paxos協議層後進入等待。X-Paxos協議層會將Consensus日誌高效地轉發給集羣內其餘節點,相比原生MySQL,日誌發送採用了Batch,Pipeline等優化手段,特別是在長傳鏈路的場景中,效率提高明顯。當日志在超過集羣半數實例上落盤後 X-Paxos會通知事務能夠進入提交步驟,不然通知事務回滾。
  Follower節點收到Leader傳遞過來的日誌之後將日誌內容Append到Consensus Log末尾,由協調者負責讀取並解析日誌後傳遞給各個回放工做線程進行數據更新。因爲Consensus日誌是基於Binlog開發,回放能夠利用MySQL-5.7的Logic clock並行複製特性。 相比MySQL-5.6中回放並行度受到表數目限制,MySQL-5.7能夠作到依賴主庫Group Commit的事務數進行併發回放,進一步提高回放的速度。

3.Failover

  RDS 5.7三節點企業版只要半數以上的節點存活就能保證集羣正常對外服務。 當Leader節點故障時會觸發從新選主的流程。 選主流程由X-Paxos驅動,在Paxos協議的基礎上,結合優先級進行新主的選舉。

  如上圖所示,左上的Case是原Leader A節點宕機,此時在選舉超時後,B節點開始嘗試選本身爲Leader, 而且C節點贊成, 那麼B成爲新的主節點,集羣正常運行。
  左下的Case 是原Leader A節點發生網絡分區,此時在選舉超時後,BC兩個節點的行爲和之間的Case相似。 A節點因爲沒法將心跳和日誌發送給BC兩個節點在超時後會降級,而後不斷嘗試選本身爲Leader,可是由於沒有其餘節點的贊成,達不成多數派,一直都不會成功。
  再看日誌數據,RDS 5.7三節點企業版 承諾在failover的狀況下不會丟失提交的數據。Paxos協議保證了無論集羣發生什麼樣的變故,在恢復後必定能保證日誌的一致性。那麼只要數據是按照日誌進行回放,就能保證全部節點的數據一致。如右上所示,假設A節點宕機或者分區前已經把3號日誌複製到了B節點,那麼在從新選舉後,B節點會嘗試將3號日誌再複製到C節點。

4.性能對比

  Group Replication是MySQL 官方出品的集羣方案。它借鑑了Galera的思想,一樣支持多主多點寫入。Group Replication實現了一個X-COM的通訊層,其新版本中已經使用了Paxos算法。目前一個GR集羣中最多能夠有9個節點,響應延時相對穩定,在節點同步日誌層面, GR使用binlog,相比Galera更加的通用。
  Group Replication 爲了保證可以多點寫入,會傳遞WriteSet的信息,其餘節點收到WriteSet後須要進行合法性驗證,確保正確處理衝突事務。在測試中,咱們發現爲了支持多點寫入而作合法性驗證是一個很是明顯的性能瓶頸點,除此以外,Group Replication仍是着重解決局域網或者是同城下一致性問題,長傳鏈路下基本沒有作任何優化。咱們在跨城場景下,使用官方5.7.17與RDS 5.7三節點企業版作了對比測試,GR的性能劣勢很是明顯,純寫入的性能只有RDS 5.7三節點企業版的五分之一,OLTP的性能也不足RDS 5.7三節點企業版的40%。

  RDS 5.7三節點企業版是對阿里業務場景很是有效的數據庫解決方案。RDS 5.7三節點企業版不只可以享受到開源社區帶來的紅利,關鍵的技術也可以作到徹底的自主、可控,可以針對業務的需求進行靈活的變動。將來 RDS 5.7三節點企業版會在此基礎上作更多的優化、例如支持多分片的Paxos, Follower提供強一致讀等功能。關於RDS 5.7三節點企業版在阿里集團內的應用,咱們會在下一篇文章中詳細展開。


原文連接 本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索