1. 程式人生 > >強一致、高可用、自動容災能力背後,阿裏X-Paxos的應用實踐

強一致、高可用、自動容災能力背後,阿裏X-Paxos的應用實踐

強一致 自動容災 高可用 阿裏x-paxos 能力

axos(分布式一致性算法)作為分布式系統的基石,一直都是計算機系統工程領域的熱門話題。Paxos 號稱是最難理解的算法,其實當真這麽困難麽?

X-Paxos 是阿裏巴巴數據庫團隊面向高性能、全球部署以及阿裏業務特征等需求,實現的一個高性能分布式強一致的 Paxos 獨立基礎庫。X-Paxos 具體有哪些優勢,能給現有的系統帶來什麽樣的收益呢?

X-Paxos 的願景:將 Paxos 帶入千萬家

雖然 Paxos 的理論提出已經 17 年了,從第一個 Paxos 的工業實現到現在也已經 11 年了,但是直到近幾年,無論是頂級會議,還是業內會議,與 Paxos 相關的文章和項目還是層出不窮。

轉向業內,真正工業級的、獨立的 Paxos 基礎庫還是相當的少見:

  • Google 並沒有開源任何 Paxos 基礎庫(連包含 Paxos 的項目都沒有開源過)。

  • Facebook 也沒有公布過包含 Paxos 的產品。

  • Apache 有 Zookeeper,但是其協議並不能支持一個高吞吐的狀態機復制,且並沒有提供獨立的第三方庫,可供快速接入。

  • 在 Github 上,能找到的 Paxos 的獨立庫,star 最高的是騰訊去年開源的 phxpaxos。

因此到目前為止,業內還鮮有成熟可靠的,可供快速使用的獨立第三方的 Paxos 庫,開源的 Paxos 生態也尚未成熟。

我們的初衷並不是要做一個 Paxos 的公共庫,X-Paxos 誕生於阿裏巴巴的分布式數據庫 AliSQL X-Cluster,但 X-Paxos 並不屬於 AliSQL X-Cluster。Paxos 是分布式系統的基石,X-Paxos 可用於解決各種各樣的分布式系統中的一致性問題。

因此在整個分布式數據庫的設計之初,我們就獨立設計了分布式一致性協議模塊,並把它獨立為 X-Paxos。X-Paxos 為 AliSQL X-Cluster 解決了分布式一致性問題,同樣可以快速賦予其他系統分布式一致性能力。

分布式一致性需求,並不是 AliSQL X-Cluster 所特有的,很多系統都存在著高可用和強一致的需求,我們把 Paxos 的能力獨立成一個基礎庫,希望能夠把這個能力帶給其他更多的系統。

例如,團隊內的同學把 X-Paxos 融入到單機 KV 數據庫 RocksDB 中,快速實現了一個分布式 KV 引擎。集團已有業務團隊把 X-Paxos 融入到業務存儲系統中,構建全新的分布式強一致存儲服務。同時也正是 AliSQL X-Cluster,成就了 X-Paxos。Google 的論文《Paxos made live》中有一段話說的很好,大意是說:Paxos 從理論到現實世界的實現之間有巨大的鴻溝,在真正實現一個 Paxos 的時候,往往需要對 Paxos 的經典理論做一些擴展。

尤其是在實現一個高性能的 Paxos 的時候,擴展點就更多了,可以參考後文的功能增強和性能優化,這往往會導致真正的 Paxos 實現都是基於一個未被完全證明的協議。這也就是傳說中,理論證明一個 Paxos 的實現,比實現這個 Paxos 還要難的原因了。因此一個成熟的 Paxos 實現很難獨立產生,往往需要和一個系統結合在一起,通過一個或者多個系統來驗證其可靠性和完備性。這也是為什麽大部分成熟的 Paxos 案例都是和分布式數據庫相結合的,例如最早的 Paxos 實現(Chubby),當前的主要 Paxos 實現(Google 的 MegaStore、Spanner,AWS 的 DynamoDB、S3 等)。而 X-Paxos 正是依托於 AliSQL X-Cluster 驗證了其可靠性和完備性。

我們的願景是希望能夠提供一個經過實踐檢驗的,高度成熟可靠的獨立 Paxos 基礎庫。使得一個後端服務能夠通過簡單的接入,就能擁有 Paxos 算法賦予的強一致、高可用、自動容災等能力。真正將晦澀難懂的 Paxos,變得平易近人,帶入千萬家。

阿裏巴巴 X-Paxos 應用實踐

X-Paxos 的整體架構

X-Paxos 的整體架構如下圖所示,主要可分為網絡層、服務層、算法模塊、日誌模塊四個部分:

技術分享

網絡層

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

服務層

服務層是驅動整個 Paxos 運行的基礎,為 Paxos 提供了事件驅動,定時回調等核心的運行功能,每一個 Paxos 實現都有一個與之緊密相關的驅動層,驅動層的架構與性能和穩定性密切相關。

X-Paxos 的服務層是一個基於 C++11 特性實現的多線程異步框架。常見的狀態機/回調模型存在開發效率較低,可讀性差等問題,一直被開發者所詬病。

而協程又因其單線程的瓶頸,而使其應用場景受到限制。C++11 以後的新版本提供了完美轉發(argument forwarding)、可變模板參數(variadic templates)等特性,為我們能夠實現一種全新的異步調用模型提供了可能。

例如,下面是 X-Paxos 內實際的一行創建單次定時任務的代碼

new ThreadTimer(srv_->getThreadTimerService(), srv_, electionTimeout_, ThreadTimer::Oneshot, &Paxos::checkLeaderTransfer, this, targetId, currentTerm_.load(), log_->getLastLogIndex());

以上一行程序,包含了定時器的創建,任意回調函數的設置,回調函數參數的轉發,並保證在回調觸發後(Oneshot)內存的自動回收。同時服務層支持嵌套回調,即在回調函數中再一次生成一個定時/即時任務,實現一個有限次的定時循環邏輯。

算法模塊

X-Paxos 當前的算法基於 unique proposer 的 multi-paxos [3] 實現,大量理論和實踐已經證明了基於 unique proposer 的 multi-paxos,性能好於 multi-paxos/basic paxos,當前成熟的基於 Paxos 的系統,大部分都采用了這種方式。

算法模塊的基礎功能部分本文不再重復,感興趣的同學可以參考相關論文 [1,2,4]。

在基礎算法的基礎上,結合阿裏業務的場景以及高性能和生態的需求,X-Paxos 做了很多的創新性的功能和性能的優化,使其相對於基礎的 multi-paxos,功能變的更加豐富,在多種部署場景下性能都有明顯的提升。

日誌模塊

日誌模塊本是算法模塊的一部分,但是出於對極致性能要求的考慮,我們把日誌模塊獨立出來,並實現了一個默認的高性能的日誌模塊。

有極致性能以及成本需求的用戶,可以結合已有的日誌系統,對接日誌模塊接口,以獲取更高的性能和更低的成本。這也是 X-Paxos 作為高性能獨立庫特有的優勢。

X-Paxos 的功能增強

我們結合廣泛的業務場景,構建開放的生態:

1. 在線添加/刪除節點,在線轉讓 leader

X-Paxos 在標準 multi-paxos 的基礎上,支持在線添加/刪除多種角色的節點,支持在線快速將 leadership 節點轉移到其他節點(有主選舉)。

2. 策略化多數派和權重化選主

目前,阿裏集團及螞蟻金服的多地有中心的架構,很多應用因其部署的特點,往往要求它在未發生城市級容災的情況下,僅在中心寫入數據庫,或調用其他分布式服務。

同時又要求在發生城市級容災的時候(同一個城市的多個機房全部不可用),可以在完全不丟失任何數據的情況下,將寫入點切換到非中心。

而經典的 multi-paxos 並不能滿足這些需求。經典理論中,多數派強同步以後即可完成提交,而多數派是非特定的,並不能保證某個/某些節點一定能得到完整的數據,並激活服務。

在實際實現中,往往地理位置較近的節點會擁有強一致的數據,而地理位置較遠的節點,一直處於非強一致節點,在容災的時候永遠無法激活為主節點,這樣就形同虛設。

同時,當中心單節點出現故障需要容災的時候,往往需要將主節點就近切換到同中心的另外一個節點。由於應用在多地的部署往往是非對稱的原因,出現單個 Region 全掛的時候,需要將主節點切到特定的 Region 內。

這些需求都需要 Paxos 在選主的時候,可以由用戶指定規則,而經典理論中同樣沒有類似的功能,添加權重也需要保證 Paxos 的正確性。

X-Paxos 在協議中實現了策略化多數派和權重化選主:

基於策略化多數派,用戶可以通過動態配置,指定某個/某些節點必須保有強一致的數據,在出現容災需求的時候,可以立即激活為主節點。

基於權重化選主,用戶可以指定各個節點的選主權重,只有在高權重的節點全部不可用的時候,才會激活低權重的節點。

3.節點角色定制化(Proposer/Accepter/Learner 的獨立配置)

在經典的 multi-paxos 實現中,一般每個節點都包含了 Proposer/Accepter/Learner 三種功能,每一個節點都是全功能節點。但是某些情況下,我們並不需要所有節點都擁有全部的功能。例如:

在經典的三個副本部署中,我們可以裁剪其中一個節點的狀態機,只保留日誌(無數據的純日誌節點,但是在同步中作為多數派計算),此時我們需要裁剪掉協議中的 Proposer 功能(被選舉權),保留 Accepter 和 Learner 功能。

我們希望可以有若幹個節點可以作為下遊,訂閱/消費協議產生的日誌流,而不作為集群的成員(不作為多數派計算,因為這些節點不保存日誌流),此時我們裁剪掉協議的 Proposer/Accepter 功能,只保留 Learner 功能。

當然還有其他的組合方式,通過對節點角色的定制化組合,我們可以開發出很多的定制功能節點,即節約了成本,又豐富了功能。

技術分享

4. Witness SDK

基於上節節點角色定制化中的單獨 Learner 角色的功能,引發了無窮的想象力。

Learner 角色,可以抽象成一個數據流訂閱者(Witness Node),整個集群中可以加入無數個訂閱者,當有新的日誌被提交的時候,這些訂閱者會收到他關心的日誌流,基於訂閱者功能。

我們可以讓一個集群很容易的實現下遊訂閱消費,日誌即時備份,配置變更推送等等的功能。

因此我們把 Learner 角色單獨封裝成了一個 SDK。基於這個 SDK,用戶可以快速地為自己的集群添加,訂閱註冊,流式訂閱定功能;結合特定的用途打造一個完整的生態。

例如,日誌流 SDK 在 AliSQL X-Cluster 中打造的生態。如下圖,采用了 X-Paxos 也可以利用 Witness SDK 快速實現分布式系統和下遊的其他系統的對接,形成一個完整的生態。

技術分享

我們拿 MySQL 的日誌(binlog)備份來舉例:

  • 普通方案。每隔固定時間 Tb,將 MySQL 生成的 binlog 文件備份到永久備份系統(OSS、S3 等)。RPO (Recovery Point Objective)為 Tb。

  • SDK 方案。X-Paxos 支持由 SDK 訂閱增量日誌,備份系統只需要簡單的實現從 SDK 流到 OSS 流的對接,即可實現流式備份。RPO (Recovery Point Objective)為 0。

除備份以外,Witness SDK 在下遊流式訂閱(DRC)、自封閉高可用系統(X-Driver)、異步只讀備庫等方面都有實戰案例,更多的應用案例在不斷的添加中。

X-Paxos 的性能優化

我們一直堅信網絡延遲不應該影響吞吐。

Batching & Pipelining

Paxos 除了設計之初的強一致和高可用以外,其高性能也是至關重要的,尤其是應用於 AliSQL X-Cluster 這種高性能分布式數據庫的時候,對協議的吞吐,延遲都提出了很高的要求。

同時作為可全球部署的分布式一致性協議,在高延遲下的性能挑戰變得尤為重要。

X-Paxos 針對高延遲網絡做了大量的協議優化嘗試和測試,並結合學術界現有的理論成果 [5,6,7] 通過合理的 Batching 和 Pipelining,設計並實現了一整套自適應的針對高延遲高吞吐和低延遲高吞吐網絡的通信模式。

極大的提升了 X-Paxos 的性能(對比見下節)。類似的優化在同類競品中還非常的罕見。

Batching 是指將多個日誌合並成單個消息進行發送;Batching 可以有效的降低消息粒度帶來的額外損耗,提升吞吐。但是過大 Batching 容易造成單請求的延遲過大,導致並發請求數過高,繼而影響了吞吐和請求延遲。

Pipelining 是指在上一個消息返回結果以前,並發的發送下一個消息到對應節點的機制,通過提高並發發送消息數量(Pipelining 數量),可以有效的降低並發單請求延遲。

同時在 transmission delay 小於 propagationdelay 的時候(高延遲高吞吐網絡),有效提升性能。

經推導可知 Batching(消息大小:M)和 Pipeling(消息並發:P)在如下關系下,達到最高吞吐 M/R * P = D。

其中 R 為網絡帶寬,D 為網絡傳播延遲(propagation delay,約為 RTT/2)

X-Paxos 結合以上理論,通過內置探測,針對不同節點的部署延遲,自適應的調整針對每個節點的 Batching 和 Pipeling 參數,達到整體的最大吞吐。

Pipeling 的引入,需要解決日誌的亂序問題,特別是在異地場景下,window 加大,加大了亂序的概率。X-Paxos 通過一個高效的亂序處理模塊,可以對底層日誌實現屏蔽亂序,實現高效的亂序日誌存儲。

技術分享

多線程,全異步的 Paxos 庫

由於 Paxos 的內部狀態復雜,實現高效的單實例多線程的 Paxos 變成一個非常大的挑戰。無論我們上面提到的 Github 中 star 最多的 phxpaxos,還是 Oracle MySQL Group Replication 中使用的 xcom,都是單線程的實現。

phxpaxos 采用了單分區單線程,多實例聚合的方式提升總吞吐,但是對單分區的性能提升非常有限;而 xcom 是一個基於協程的單線程實現。單線程的 Paxos 實現,在處理序列化/反序列化,分發、發包等邏輯的時候都為串行執行,性能瓶頸明顯。

X-Paxos 是完全基於多線程實現的,可以在單個分區 Paxos 中完全的使用多線程的能力,所有的任務都有通用的 woker 來運行,消除了 CPU 的瓶頸。

依賴於服務層的多線程異步框架和異步網絡層,X-Paxos 除了必要的協議串行點外,大部分操作都可以並發執行,並且部分協議串行點采用了無鎖設計,可以有效利用多線程能力,實現了 Paxos 的單分區多線程能力,單分區性能遠超競品,甚至超過了競品的多分區性能。

Locality Aware Content Distribution

基於 unique proposer 的分布式系統存在的一個瓶頸點就是主節點是唯一的內容輸出源,當集群存在大量節點的時候,主節點的大量網絡收發工作會導致主節點的負載過大,引發 CPU 和帶寬的瓶頸。

在全國/全球部署的時候,所有節點和主節點之間的直接通信會造成跨 Region 之間的長傳/國際鏈路的帶寬占用過大。

X-Paxos 是旨在解決全球分布式強一致問題的 Paxos 獨立庫,在設計之初就考慮到了這個問題。

X-Paxos 在穩態運行時會感知各個節點之間的網絡延遲(物理距離),並形成級聯拓撲,有效降低主節點的負載,降低長傳鏈路的帶寬使用;而在有節點異常的時候,又會自動重組拓撲,保證各個存活節點間的同行的正常進行。

同時 X-Paxos 支持由業務來設定重組拓撲的規則,業務可以根據自己 APP 的部署架構和延遲特性來針對性的設置拓撲重組規則。

技術分享

可插拔日誌

X-Paxos 和現有的大部分 paxos 庫很大的不同點就是 X-Paxos 支持可插拔的日誌模塊。日誌模塊是 Paxos 中一個重要的模塊,它的持久化關系到數據的一致性,它的讀寫性能很大程度上會影響協議整體的讀寫性能。

當前大部分獨立 Paxos 庫都是內置日誌模塊,並且不支持插拔的。這會帶來兩個弊端:

默認的日誌模塊提供通用的功能,很難結合具體的系統做針對性的優化。

現有的系統往往已經存在了 WAL(Write Ahead Log),而 Paxos 協議中需要再存一份。這使得 a)單次 commit 本地需要 sync 2 次(影響性能);b)雙份日誌浪費了大量的存儲。

例如,phxpaxos 內置的日誌模塊采用的 LevelDB,作為日誌系統其操作大量冗余,無針對優化,性能堪憂。

同時采用 phxpaxos 的 phxsql 單節點需要既保存 binlog,又保存 Paxos log(在獨立的 phxbinlogsvr 中),嚴重影響了性能,浪費了存儲空間。

而采用 X-Paxos 的 AliSQL X-Cluster 直接改造了現有的 binlog 模塊,對接到 X-Paxos 的日誌模塊,單節點僅一份日誌,既降低了存儲,又提高了性能。

X-Paxos 的分布式正確性驗證

對於一個分布式強一致協議來說,正確性是生命線。上文已經提及,一個分布式強一致協議,很難完整的理論證明其正確性,再加上工程實現的問題,困難就更多了。

我們從理論和工程兩方面用了大量的理論和技術手段來保證 X-Paxos 的正確性和完備性。

Jepsen

Jepsen 是開源社區比較公認的分布式數據庫的測試框架。Jepsen 驗證過程包括 VoltDB、CockroachDB、Galera、MongoDB、etcd 在內的幾乎所有的主流分布式數據庫/系統,檢驗出了不少的問題。

X-Paxos 完成了和 Jepsen 的對接,並驗證了各個分布式數據庫已有的 case。

TLA+

TLA+ 是 Paxos 創始人、圖靈獎獲得者 Leslie Lamport 發明的一種形式化規約語言。 TLA+ 專用於設計、建模和驗證分布式並發系統。Amazon DynamoDB/S3/EBS 和 MicrosoftCosmos DB 都通過 TLA+ 的模型驗證發現了不少問題。

X-Paxos 目前已經通過了 TLA+ 的模型驗證。

隨機異常系統

我們搭建了一套自動隨機異常驗證系統,可以自動化驗證各種異常場景下的協議正確性和穩定性。驗證 X-Paxos 在模擬網絡丟包、閃斷、隔離,磁盤故障等情況下的功能正確和數據一致。

異常回歸系統

X-Paxos 擁有一套異常 case 回歸系統,對於曾經出現過或者預期的並發異常 case,都會加到異常 case 庫中,進行日常回歸驗證。同時異常 case 庫也在不斷的豐富中。

X-Paxos 的競品分析和對比

XCOM (MySQL Group Replication)

MySQL GroupReplication 是 MySQL 官方借鑒 Galera 的思想,在 MySQL 上構建分布式強一致集群的一個插件。

MySQL Group Replication 早期采用的分布式協議是 CoroSync,它是由 Red Hat 開發的基於 Totem(The Totem Single-Ring Ordering and MembershipProtocol)[8] 協議開發的分布式一致性協議庫。

由於 Totem 算法本身存在的一些局限性能原因,從 MySQL 5.7.9 版本以後,官方采用了自己研發的基於類 Paxos(Mencius)[10] 的一致性協議庫 XCOM。

XCOM 是 MySQL Group Replication 的核心組件,稱為 Group Communication Core[9]。我們分析了 XCOM 的源碼,XCOM 內部是一個由純 C 語言編譯的核心模塊以及由 C++ 實現的 proxy 的系統。

純 C 模塊由單線程驅動,依賴協程實現任務調度。因此 Client(MySQL GroupReplication Plugin)必須用 TCP 連接向 XCOM 發送請求。

因此 XCOM 存在如下的不足之處:

  • 單線程驅動,無多線程能力。架構決定,很難突破。

  • 通信流需要額外的一次 TCP 協議棧。在內存拷貝都要精細計算的應用中,線程間多一次網絡通信很難接受。

  • XCOM 雖然實現了 Batching 和 Pipelining,但是其值均為固定值,很難適應真實的場景。官方的文檔中也提到了這一點[9]。這也使得 MySQL Group Replication 在跨 Region 場景中性能很不理想(見 AliSQL X-Cluster 對比測試)。

phxpaxos (phxsql)

phxpaxos 是騰訊推出的基於 Paxos 協議的獨立庫,它和 MySQL 結合後推出了 phxsql 項目,也是基於 MySQL 實現的分布式強一致 MySQL 集群。

phxpaxos 可獨立用於其他項目,是目前 Github 上 star 最多(1000+)的 Paxos 獨立庫。關於 phxsql 的細節本文不再敘述,可以參考(AliSQL X-Cluster 的競品分析部分),我們這裏主要分析 phxpaxos。

phxpaxos 也是基於 multi-Paxos 實現的獨立庫,架構上采用單 Paxos 單線程設計,但是支持多 Paxos 分區以擴展多線程能力,這種擴展需要多數據進行提前分區。

因此 phxpaxos 的不足之處,如下:

單 Paxos 對象只支持單線程,可支持多 Paxos 對象,共享網絡層。

不支持 pipelining,在跨 Region 環境(高延遲)下,幾乎不可用。

多份日誌冗余,基於 LevelDB 的日誌系統性能瓶頸。

性能對比

我們還是拿騰訊的 phxpaxos 作為競品和我們進行對比(XCOM 無獨立組件,可間接參考 MySQL Group Replication 和 AliSQL X-Cluster 的對比測試結果)。

我們分別在 a) Region 內 3 節點部署 b) 3 個 Region 各一個節點部署調節下,以不同的請求大小進行壓測。

技術分享
技術分享

從上面兩個對比圖中可以看到:

  • X-Paxos 的同 Region 性能是 phxpaxos 的 100 倍以上。

  • 跨 Region 場景下 phxpaxos 幾乎不可用,而 X-Paxos 在 444Byte(sysbench insert 場景單請求大小),性能只有 3.5% 的下降,幾乎不影響吞吐。

X-Paxos的現狀與未來

現狀:目前 X-Paxos 一期已經發布上線。基於 X-Paxos 的集團數據庫團隊產品 AliSQL X-Cluster 已在集團內廣泛使用。X-Paxos 和業務系統結合打造的分布式服務也相繼落地上線。

未來:Paxos 是分布式系統的基石,即使是近幾年,學術界關於 Paxos 的文章,新的演進方向一直在不斷的湧現,我們的 X-Paxos 也會不停的發展,以更好的適應集團內外的需求。

未來主要的發展方向如下:

高效率,多分區支持。基於新的異步框架,實現一個深度底層共享的多分區 Paxos。

多節點強一致讀。經典的 multi-paxos 只有在 leader 上才能提供強一致讀,spanner和業界都有一些在多節點上提供強一致讀的方案,但還是有比較明顯的缺陷。

參考文件:

[1]The part-time parliament

[2]The Chubby lock service for loosely-coupled distributed systems

[3]Paxos Made Simple

[4]Paxos Made Live - An Engineering Perspective

[5]Everything You Ever Wanted to Know About Message Latency

[6]Adaptive Batching for Replicated Servers

[7]Tuning Paxos for high-throughput with batching and pipelining

[8]The Totem single-ring ordering and membership protocol

[9]Group Replication: A Journey to the Group Communication Core

[10]Mencius: Building Efficient Replicated State Machines for WANs

技術分享

10多年 Linux C/C++ 底層研發經驗,數據庫內核研發經驗。長期從事 MySQL 內核研發,分布式數據庫研發工作。同時作為數據庫內核負責人多次參加阿裏巴巴雙十一購物節。AliSQL 項目主要開發人員,主導阿裏的分布式強一致協議 X-Paxos 開發工作。

技術分享


本文出自 “雪夜雕零” 博客,請務必保留此出處http://wangxy.blog.51cto.com/12562290/1954440

強一致、高可用、自動容災能力背後,阿裏X-Paxos的應用實踐