微信PaxosStore內存篇:十億Paxos/分鐘的挑戰

zx19930731 7年前發布 | 8K 次閱讀 分布式/云計算/大數據 paxos

微信存儲QuorumKV是一個分布式的存儲系統,覆蓋但不限于微信后臺核心業務:賬號/用戶信息/關系鏈/朋友圈,等等。

過去的一年,我們受Google MegaStore啟發,重新設計了一套全新的分布式存儲系統,即PaxosStore分布式存儲,并于最近半年對核心業務存儲做了架構改造,目前已成功上線并完成了數千臺機器的平滑切換,系統首次訪問成功率提升一個量級,并獲得更好的容災能力,可用性顯著增強。

內存云作為微信PaxosStore存儲體系的組成部分,目前存儲著微信基礎賬號、消息計數等核心用戶數據,每天峰值請求高達數十億/分鐘,本文將向大家分享內存云的Paxos改造過程。

背景

微信內存云,目前有2千多臺機器:單機內存64GB,存儲盤為機械盤。作為核心存儲之一,內存云承載了基礎賬號、消息計數等核心數據的存儲,保障微信登錄、消息收發等微信基礎功能。內存云每天服務峰值請求十多億/分鐘,讀寫比約為3.3:1。基于QuourmKV的內存云具體架構如圖1所示:

圖1 QuorumKV架構

微信QuourmKV陪伴內存云走過了數次擴容,經歷元旦、春晚等例行節日請求爆發增長的洗禮,也沉淀著不少故障處理經驗(不限內存云)。本文主要描述新架構如何根本性地改善QuorumKV的容災能力(即CAP中,保證C的前提下增強A),在不犧牲性能的前提下,消滅部分故障場景下的最終失敗和人為介入。

QuorumKV本質上是一個NWR協議(N為3,W/R為2)的分布式存儲,和其他NWR協議不同的地方在于:QuorumKV將NWR應用在版本上,當且僅當版本達成一致的情況下讀寫單機數據,從而保證強一致性。但是這里引入了2個問題:

  • 數據寫一份,依靠異步同步至對機;
  • 當WR無法形成多數時,單Key不可用,需進行修復。

不要小看了這2個問題,這是目前QuorumKV的絕大部分日常故障導致失敗的根源,特別是對寫量大的模塊而言:

  • 數據機故障離線,部分Key最新數據在故障機上,不可用;
  • 版本機故障離線,部分Key(版本不平)仲裁失敗,不可用。

表2 分布式協議對比

明確問題的根源是QuorumKV采用的NWR分布式協議,那么在保證強一致性的前提下可行的解決方案為Paxos/Raft分布式協議。表2列出了我們在協議選擇上的一些考量:采用無租約的方式使得系統在保證強一致性的前提下達到最大的可用性;相對而言,租約的方式必然引入主備切換導致的不可用。

在對比調研過一些業界方案(etcd/megastore等)后,我們最終確定新架構協議方案是:無租約版Paxos分布式協議(如圖3所示)。

圖3 新架構(無租約版Paxos分布式協議)

面對挑戰

接下來需要做的事情是,基于Paxos分布式協議在機械盤上搭建一套穩定高性能的分布式存儲。

挑戰1:Paxos分布式協議

我們在談及Paxos算法時,通常會提及Leslie Lamport大神的Paxos Made Simple;但基于Paxos算法的分布式協議不止與此,圖4列出一個完整協議涉及的3個層次。

圖4 Paxos分布式協議

Paxos算法

PaxosStore孕育了2套Paxos算法組件:Paxos Certain組件和Paxos KV組件,內存云使用的正是其中的PaxosKV算法組件。Paxos KV組件核心代碼1912行,經過嚴格測試,目前用于線上多個Key-Value存儲模塊,包括但不限于:用戶賬號信息存儲、朋友圈存儲等。

PaxosLog

在構建PaxosLog(簡稱為PLog)時,我們針對Key-Value存儲做了2項優化。

第一,PLog as DB

普通青年的通常做法是PLog和DB分離:增量更新記錄在PLog中,并在Chosen之后順序應用到DB中。這里的問題在于:

  • 至少2次寫操作:1次PLog寫,1次DB寫。
  • Key和PLog的對應關系:
  • N : 1 讀寫性能受限與單個PLog;
  • 1 : 1 相同的數據重復寫2次。

圖5 精簡1:plog as db

進步青年思考了下得出PLog as DB方案:我們希望Key和PLog保持1:1的對應關系,從而達到最大的并發性能,同時又不引入重復寫。

第二, 精簡的PLog: 只保留最新的LogEntry

圖6 精簡2:最新的LogEntry

作為PLog as DB的延伸,既然每個最新LogEntry包含全量的數據,那么物理上保留連續的PLog就沒有必要了。

簡單輕便的PLog結構,帶來的優勢還有:

  • LogCompact伴隨每次寫進行,不占用額外的存儲和計算開銷;
  • Log Catch-Up通過分發最新的LogEntry即可完成,無需順序追流水或者Snapshot,應用DB。

基于PaxosLog的強一致性讀寫協議

強一致性讀協議

圖7 強一致性讀協議

強一致性讀協議本身和Paxos算法沒有太大關系,要點是多數派:廣播的方式獲取集群中多數機器(包含自身)的PLog狀態,即最新的LogEntry位置和對應LogEntry處于Pending/Chosen狀態。

  • 當集群中多數在Log Entry i上處于Chosen狀態時,可以確定Log Entry i是最新的。對于讀多寫少的業務,主要面對這種情況,整體讀就可以非常輕量且失敗非常低。
  • 當集群中多數在Log Entry i上處于Pending狀態時,無法確定Log Entry i-1是否最新,因為可能存在某臺機器Log Entry i處于Chosen狀態。對于讀多寫多的業務,讀的失敗就會相對高很多。可行的優化有:(1)盡量收集多機的狀態信息,如果所有機器的Log Entry i都處于Pending狀態,就可以確定Log Entry i-1的數據是最新的;(2)使用隱含條件:只有A/B機器可讀寫。

強一致性寫協議

強一致性寫協議的大多數問題來自Paxos算法本身,這里我們主要做了3項優化(或者說解決3個問題)。

第一,優化寫。

  • The leader for each log position is a distinguished replica chosen alongside the preceding log position’s consensus value. The leader arbitrates which value may use proposal number zero. The first writer to submit a value to the leader wins the right to ask all replicas to accept that value as proposal number zero. All other writers must fall back on two-phase Paxos.

上述文字摘抄自MegaStore: FastWrites部分,描述:LogEntry i-1值的歸屬者可以在寫LogEntry i時跳過Paxos算法的Prepare階段直接進行Accept階段。基于這段迷一樣的文字,我們實現Paxos優化寫算法:減少1次寫盤、2次協議消息發送、2次協議消息接收;最終實現了寫耗時和失敗的降低,如圖8所示。

圖8 優化寫和普通寫的性能對比

第二,如何確定誰的提議寫成功了?

Paxos算法只保證LogEntry i確定唯一值,但在多個Proposer的條件下(即A/B機均可發起強一致寫),只有確定值的歸屬者可以返回成功。這里我們復用了etcd中requestid的方案。

圖9 requestid方案

其中member_id用于區分不同的Proposer,timestamp為毫秒級別的時間戳,req_cnt隨寫請求單調遞增。基于requestid方案可以滿足單機25w/s的寫請求,足夠了。

備注:requestid只需要在單個plog緯度上保證唯一即可。

第三,Paxos活鎖問題。

Paxos算法本身不保證終止性,當出現寫沖突時算法可能永遠終結不了,即存在活鎖問題;因此在實際工程中我們需要進行一些權衡:

  • 限制單次Paxos寫觸發Prepare的次數;
  • 隨機避讓。

我們目前使用了Prepare次數限制策略,從現網監控來看由寫沖突導致的失敗比例極小:

圖10 Prepare次數限制導致的失敗監控

挑戰2:基于機械盤的DirectIO存儲

我們在新架構上采用DirectIO的方案實現了一套保證數據安全落盤的存儲組件,DirectIO方案與其他兩種寫盤方案的對比如表格11所示。

表11 寫方式比較

然而僅僅保證數據安全落盤還不夠,我們還要做到穩定:基于Bitcask寫模型搭建的存儲,需要定期的整理磁盤文件(我們稱之為Merge),以重復利用磁盤空間,其中涉及操作有:Merge新文件寫盤、舊文件刪除,對外表現為:Merge寫和正常寫競爭、文件刪除引起系統卡頓。為克服這2個問題,我們做了以下優化。

  • 控制Merge寫盤速度和大小。
  • 在DirectIO的4K塊中引入BlockID,以支持文件的循環利用(不再刪文件)。

圖12 4K DirectIO BlockID

挑戰3:復雜的現網場景

機械盤RaidCache

RaidCache以電池作為后盾,可以在WriteBack模式下持有待寫盤的數據批量寫盤,以極大提升機械盤的寫盤性能;缺點在于當電池掉電時,為了數據安全必須從WriteBack模式切換到WriteThrough模式,寫盤性能急劇下降(真實的機械盤)。磁盤從WB降級為WT是現網運營中常見的問題,通常1~2小時后電池充電完畢即可重回WB模式,我們來看看這1~2小時磁盤退化的影響。

單次磁盤退化導致磁盤寫操作耗時和失敗率升高,通常情況下被Paxos協議本身的多數派所容忍;但是本機作為Proposer主動發起寫時,寫盤失敗帶來的就是單次寫請求失敗,前端會自動跳轉對機重試,此時問題來了:磁盤退化者寫失敗之前將LogEntry置于Pending,對機重試的最終結果將Pending推成Chosen,但此時requestid表明Chosen值源于磁盤退化者,對機寫被搶占,返回最終失敗。

簡單的說,磁盤退化期間寫最終失敗較高:通過將requestid前傳到對機,讓對機用已有的requestid重試可以將寫最終失敗降低1個數量級。

PLog對齊

當單機包含kw級別的PLog時,保持系統中所有PLog均處于對齊狀態就變得很困難;但只有在所有PLog均處于對齊狀態時,系統才能保持最大化的可用性。經歷一番權衡后,我們的系統中掛載了以下邏輯(按時效性排序)來保證PLog對齊:

  • 失敗(本地落后)觸發異步Catch-Up;
  • 三級超時隊列:如果LogEntry超時后依舊處于Pending狀態,就觸發協議寫重試;
  • 全量數據校驗:校驗數據一致性的同時也觸發PLog對齊。

LeanerOnly模式

機器重啟后發現文件丟失,數據被回退了怎么辦?Paxos協議保證了絕大部分情況下強一致性和可用性,但不是全部。

  • 某LogEntry承諾機器A的Paxos請求后,因為數據回退狀態清空,重新上線后承諾機器B的Paxos請求,但是前后2次承諾相互矛盾,從而導致數據不一致。

上述描述的是拜占庭失敗導致的數據不一致,這種失敗違反了Paxos協議的假設前提;但現網運營中確實又需要處理這種情況,從而有了LeanerOnly模式的引入。

  • LeanerOnly模式下,本機只接收Chosen后的LogEntry,不參與Paxos協議寫,也就不會違背任何承諾。
  • 三級超時隊列,使得LogEntry盡快走向Chosen。
  • 異步Catch-Up和全量數據校驗使得系統PLog較快對齊。

假設進入LeanerOnly模式2小時后,系統中舊LogEntry處于Pending狀態的可能性可以忽略不計,那么該機可以解除LeanerOnly模式。

成果

除了上文描述的優化外,我們還定制了一套本地遷移的方案用于新舊架構的平滑切換,由于篇幅限制,在此就不一一展開了。最終我們實現上千臺機器安全無故障的從QuorumKV架構切換到新架構,下面同步下新架構的性能數據和容災能力。

性能數據

壓力測試條件:Value約為120B,讀寫3.3 : 1。

壓力測試機型:64GB內存,機械盤。

表13 新舊架構性能對比

圖14 新舊架構平均耗時和最終失敗對比

具體數據如表13所示,可以看出在請求量相當的條件下,新架構在平均耗時和最終失敗上都優與舊架構;并且新架構只需要6臺機器。

備注:新架構部署上少了3臺機器,帶來單機約50%的內存和磁盤增長(容納3份數據)。

系統可用性

實例1:網絡故障期間可用性對比

圖15 網絡故障期間 PaxosStore內存云首次訪問失敗率監控曲線

圖16 網絡故障期間 QuorumKV內存云首次訪問失敗率監控曲線

某次內網故障期間(持續約半小時),PaxosStore內存云展現了卓越的容災能力:圖15為故障期間PaxosStore內存云的首次訪問失敗率監控,可以看到失敗率是十分平穩的(因為網絡故障期間前端請求有所降低,失敗率反而小了些);與之對應QuorumKV內存云則表現不理想。

備注:需要強調的是得益與微信后臺整體優秀的容災設計,用戶對本次網絡故障感知度很低。

實例2:某城市切換架構前后失敗率對比

圖17 PaxosStore內存云首次訪問失敗率監控曲線

圖18 QuorumKV內存云首次訪問失敗率監控曲線

圖17和圖18分別給出了新舊架構KV首次訪問失敗率監控曲線(百萬分之一),可以看到切換后系統的首次訪問成功率從5個9提升至6個9,系統可用性得以增強。

備注: 此處為極為微觀的數據,前端會有簡單的重試達到100%成功。

小結

全新的內存云存儲,通過精簡的PLog as DB、分布式強一致性讀寫協議等一連串優化,在性能上得到顯著提升;結合DirectIO存儲系統、PLog全量對齊等,系統首次訪問失敗率指標下降一個量級。

PaxosStore是微信內部一次大規模Paxos工程改造實踐,創新性地實現了非租約Paxos架構,未來還有后續文章和開源計劃,敬請期待。

 

 

來自:http://www.infoq.com/cn/articles/one-billion-paxos-minutes-of-challenge

 

 本文由用戶 zx19930731 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!