Raft實戰——線性一致性實現方法及性能優化

2021-02-16 Q的博客

本文是《Raft 實戰系列——理論篇》的最後一文,首先介紹 Raft 協議場景採用「寫主讀從」、「寫主讀主」兩種模式均無法保障線性一致性的原因;其次介紹基於 Raft 協議實現工程系統時,如何來保證線性一致性;最後介紹 Raft 針對一致性所做的讀性能優化的具體策略。

系列前文快速連結:

在前面5篇文章中,我們分別介紹了《Raft 基本概念》、《Raft 選主機制》、《Raft 基於日誌複製實現狀態機機制》、《Raft 選主及狀態機維護的安全性》、《Raft 集群變更防腦裂 & 解決數據膨脹》,《線性一致性概念介紹》,系統學習 Raft 協議建議從頭閱讀。

--

1. 線性一致性基礎

數據一致性是為提升系統可用性所採用多副本機制所帶來的新問題。在上文《Raft 實戰番外篇——線性一致性》中我們重點解析了線性一致性的模型及挑戰,對線性一致性不了解的同學,先閱讀上文再學習下面內容會更容易理解吸收~

2. Raft 線性一致性讀在了解了什麼是線性一致性之後,我們將其與 Raft 結合來探討。首先需要明確一個問題,使用了 Raft 的系統都是線性一致的嗎?不是的,Raft 只是提供了一個基礎,要實現整個系統的線性一致還需要做一些額外的工作。假設我們期望基於 Raft 實現一個線性一致的分布式 kv 系統,讓我們從最樸素的方案開始,指出每種方案存在的問題,最終使整個系統滿足線性一致性2.1 寫主讀從缺陷分析寫操作並不是我們關注的重點,如果你稍微看了一些理論部分就應該知道,所有寫操作都要作為提案從 leader 節點發起,當然所有的寫命令都應該簡單交給 leader 處理。真正關鍵的點在於讀操作的處理方式,這涉及到整個系統關於一致性方面的取捨。在該方案中我們假設讀操作直接簡單地向 follower 發起,那麼由於 Raft 的 Quorum 機制(大部分節點成功即可),針對某個提案在某一時間段內,集群可能會有以下兩種狀態:某次寫操作的日誌尚未被複製到一少部分 follower,但 leader 已經將其 commit。某次寫操作的日誌已經被同步到所有 follower,但 leader 將其 commit 後,心跳包尚未通知到一部分 follower。以上每個場景客戶端都可能讀到過時的數據,整個系統顯然是不滿足線性一致的。2.2 寫主讀主缺陷分析在該方案中我們限定,所有的讀操作也必須經由 leader 節點處理,讀寫都經過 leader 難道還不能滿足線性一致?是的!! 並且該方案存在不止一個問題!!問題一:狀態機落後於 committed log 導致髒讀回想一下前文講過的,我們在解釋什麼是 commit 時提到了寫操作什麼時候可以響應客戶端:所謂 commit 其實就是對日誌簡單進行一個標記,表明其可以被 apply 到狀態機,並針對相應的客戶端請求進行響應。也就是說一個提案只要被 leader commit 就可以響應客戶端了,Raft 並沒有限定提案結果在返回給客戶端前必須先應用到狀態機。所以從客戶端視角當我們的某個寫操作執行成功後,下一次讀操作可能還是會讀到舊值。這個問題的解決方式很簡單,在 leader 收到讀命令時我們只需記錄下當前的 commit index,當 apply index 追上該 commit index 時,即可將狀態機中的內容響應給客戶端。假設集群發生網絡分區,舊 leader 位於少數派分區中,而且此刻舊 leader 剛好還未發現自己已經失去了領導權,當多數派分區選出了新的 leader 並開始進行後續寫操作時,連接到舊 leader 的客戶端可能就會讀到舊值了。因此,僅僅是直接讀 leader 狀態機的話,系統仍然不滿足線性一致性。2.3 Raft Log Read為了確保 leader 處理讀操作時仍擁有領導權,我們可以將讀請求同樣作為一個提案走一遍 Raft 流程,當這次讀請求對應的日誌可以被應用到狀態機時,leader 就可以讀狀態機並返回給用戶了。這種讀方案稱為 Raft Log Read,也可以直觀叫做 Read as Proposal。為什麼這種方案滿足線性一致?因為該方案根據 commit index 對所有讀寫請求都一起做了線性化,這樣每個讀請求都能感知到狀態機在執行完前一寫請求後的最新狀態,將讀寫日誌一條一條的應用到狀態機,整個系統當然滿足線性一致。但該方案的缺點也非常明顯,那就是性能差,讀操作的開銷與寫操作幾乎完全一致。而且由於所有操作都線性化了,我們無法並發讀狀態機。3. Raft 讀性能優化接下來我們將介紹幾種優化方案,它們在不違背系統線性一致性的前提下,大幅提升了讀性能。3.1 Read Index與 Raft Log Read 相比,Read Index 省掉了同步 log 的開銷,能夠大幅提升讀的吞吐一定程度上降低讀的時延。其大致流程為:Leader 在收到客戶端讀請求時,記錄下當前的 commit index,稱之為 read index。Leader 向 followers 發起一次心跳包,這一步是為了確保領導權,避免網絡分區時少數派 leader 仍處理請求。等待狀態機至少應用到 read index(即 apply index 大於等於 read index)。這裡第三步的 apply index 大於等於 read index 是一個關鍵點。因為在該讀請求發起時,我們將當時的 commit index 記錄了下來,只要使客戶端讀到的內容在該 commit index 之後,那麼結果一定都滿足線性一致(如不理解可以再次回顧下前文線性一致性的例子以及2.2中的問題一)。3.2 Lease Read與 Read Index 相比,Lease Read 進一步省去了網絡交互開銷,因此更能顯著降低讀的時延。基本思路是 leader 設置一個比選舉超時(Election Timeout)更短的時間作為租期,在租期內我們可以相信其它節點一定沒有發起選舉,集群也就一定不會存在腦裂,所以在這個時間段內我們直接讀主即可,而非該時間段內可以繼續走 Read Index 流程,Read Index 的心跳包也可以為租期帶來更新。Lease Read 可以認為是 Read Index 的時間戳版本,額外依賴時間戳會為算法帶來一些不確定性,如果時鐘發生漂移會引發一系列問題,因此需要謹慎的進行配置。3.3 Follower Read在前邊兩種優化方案中,無論我們怎麼折騰,核心思想其實只有兩點:保證在讀取時的最新 commit index 已經被 apply。其實無論是 Read Index 還是 Lease Read,最終目的都是為了解決第二個問題。換句話說,讀請求最終一定都是由 leader 來承載的。那麼讀 follower 真的就不能滿足線性一致嗎?其實不然,這裡我們給出一個可行的讀 follower 方案:Follower 在收到客戶端的讀請求時,向 leader 詢問當前最新的 commit index,反正所有日誌條目最終一定會被同步到自己身上,follower 只需等待該日誌被自己 commit 並 apply 到狀態機後,返回給客戶端本地狀態機的結果即可。這個方案叫做 Follower Read。注意:Follower Read 並不意味著我們在讀過程中完全不依賴 leader 了,在保證線性一致性的前提下完全不依賴 leader 理論上是不可能做到的。如果你一路堅持看了下來,相信已經對 Raft 算法的理論有了深刻的理解。當然,理論和工程實踐之間存在的鴻溝可能比想像的還要大,實踐中有眾多的細節問題需要去面對。在後續的源碼分析及實踐篇中,我們會結合代碼講解到許多理論部分沒有提到的這些細節點,並介紹基礎架構設計的諸多經驗,敬請期待!

相關焦點

  • Raft實戰(番外篇)—— 線性一致性介紹
    本文為《Raft 實戰系列理論篇》的番外篇,其講述的「線性一致性」,也是 Raft 協議在工程實踐中所必須考慮的問題。
  • 深度解析 Raft 分布式一致性協議(長文)
    算法方面講解:選主機制、基於日誌實現狀態機機制、安全正確維護狀態機機制;工程實現方面講解:集群成員變更防腦裂策略、解決數據膨脹及快速恢復狀態機策略、線性一致讀性能優化策略等。註:本篇內容較多,建議在大屏 PC 或平板閱讀,效果更佳。1. 概述1.1 Raft 是什麼?
  • hashicorp Raft 代碼閱讀筆記
    對一系列值達成共識,比如set x =10/x =20,對外就表現出一致性。所以一致性是對外呈現的狀態,共識是達成一致結果的一種手段和過程。一致性分類:一致性分為嚴格一致性,強一致性(全局時鐘的線性一致性和順序一致性),弱一致性;共識算法為了解決分布式系統的一致性問題,前人提出了許多算法。
  • 基於Raft 深度優化,騰訊雲金融級消息隊列 CMQ 高可靠算法詳解
    隨著網際網路時代數據規模的爆發式增長,傳統的單機系統在性能和可用性上已經無法勝任,分布式系統具有擴展性強、可用性高、廉價高效等優點得以廣泛應用。 但與單機系統相比,分布式系統在實現上要複雜很多。CAP 理論是分布式系統的理論基石,它提出以下 3 個要素:l  Consistency(強一致性):任何客戶端都可以訪問到同一份最新的數據副本。
  • 分布式|Paxos和Raft複習
    參考資料《使用Multi-Paxos協議的日誌同步與恢復》 X-Paxos是X-DB中的Multi-Paxos實現,通過異步流水線化、Batching和Pipeline等手段提升性能。參考資料《阿里如何實現高性能分布式強一致的獨立 Paxos 基礎庫》PaxosStore是我司WXG基於Paxos實現的分布式一致性中間件,在微信的用戶帳號管理、用戶關係管理、即使消息、社交網絡、在線支付等場景中廣泛應用。
  • 分布式一致性算法:Raft 算法
    Raft 算法是可以用來替代 Paxos 算法的分布式一致性算法,而且 raft 算法比 Paxos 算法更易懂且更容易實現。本文對 raft 論文進行翻譯,希望能有助於讀者更方便地理解 raft 的思想。
  • Paxos、Raft不是一致性算法/協議?
    今天,我們來簡單聊聊「Consistency」這個詞,即一致性。Paxos、Raft等通常被誤稱為「一致性算法」。但是「一致性(Consistency)」和「共識(Consensus)」並不是同一個概念。Paxos、Raft等其實都是共識(Consensus)算法。
  • 【譯】Raft 學生指南(一)
    這門課在早期有一些基於 Paxos 一致性算法的實驗,但是今年,我們決定將其轉移到Raft[2]。Raft 是「以易於理解為目標而被設計出來的」,並且,我們的期望這個改變可以使學生的生活變得更加輕鬆。Raft,對於你們當中那些剛剛接觸到它的人來說,這個協議網站[7]上的文字是最好的描述:Raft是一個以易於理解為目標而被設計的一致性算法。它在容錯和性能方面和Paxos是等效的。區別是它被分解為相對獨立的子問題,並且它乾淨利落地解決了實際系統中需要的所有主要部分。
  • 360海量數據存儲 zeppelin設計與實現
    (不過我認為ceph 底下的rados實現的還不夠純粹, 因為rados對應的value 是類似於一個對象文件. 比如在基於librados 實現librbd的時候很多對象屬性的一些方法是用不上的)所以才有各種不同的multi-paxos 的實現  那麼paxos make live 這個文章裡面主要講的是如何使用multi paxos 實現chubby 的過程, 以及實現過程中需要解決的問題, 比如需要解決磁碟衝突, 如何優化讀請求, 引入了Epoch number等, 可以看成是對實現multi-paxos 的實踐  2.
  • 談談paxos, multi-paxos, raft
    , 所以最簡單的方法就是實現每一個問題獨立運行一個Paxos 的過程, 但是這樣每一個問題都需要Prepare, Accept 兩個階段才能夠完成.所以才有各種不同的multi-paxos 的實現那麼paxos make live 這個文章裡面主要講的是如何使用multi paxos 實現chubby 的過程, 以及實現過程中需要解決的問題, 比如需要解決磁碟衝突, 如何優化讀請求, 引入了Epoch number等, 可以看成是對實現multi-paxos 的一些關於 multi-paxos 和 raft 的關係
  • 原理+代碼|Python實戰多元線性回歸模型
    其中多元共線性這個問題將貫穿所有的機器學習模型,所以本文會「將原理知識穿插於代碼段中」,爭取以不一樣的視角來敘述和講解「如何更好的構建和優化多元線性回歸模型」。主要將分為兩個部分:詳細原理Python 實戰Python 實戰Python 多元線性回歸的模型的實戰案例有非常多,這裡雖然選用的經典的房價預測
  • 一文搞懂Raft算法
    raft是工程上使用較為廣泛的強一致性、去中心化、高可用的分布式協議。
  • Etcd 架構與實現解析
    Etcd 如何實現一致性的?說到這個就不得不說起raft協議。但這篇文章不是專門分析raft的,篇幅所限,不能詳細分析,有興趣的建議看文末原始論文地址以及raft協議的一個動畫。便於看後面的文章,我這裡簡單做個總結:raft通過對不同的場景(選主,日誌複製)設計不同的機制,雖然降低了通用性(相對paxos),但同時也降低了複雜度,便於理解和實現。
  • Python 實戰多元線性回歸模型,附帶原理+代碼
    其中多元共線性這個問題將貫穿所有的機器學習模型,所以本文會「將原理知識穿插於代碼段中」,爭取以不一樣的視角來敘述和講解「如何更好的構建和優化多元線性回歸模型」。主要將分為兩個部分:Python 實戰Python 多元線性回歸的模型的實戰案例有非常多,這裡雖然選用的經典的房價預測,但貴在的流程簡潔完整,其中用到的精度優化方法效果拔群,能提供比較好的參考價值。
  • 《船長漂流記》raft喝水方法介紹
    導 讀 《船長漂流記》raft遊戲中怎么喝水呢?
  • 分布式一致性機制整理
    ,分為弱一致性和強一致性。事務提交過程分為兩階段:提交事務請求(投票階段)執行事務提交(執行階段)如果都是參與者都回復Yes,則協調者向參與者發送提交請求,否則發送回滾請求參與者根據協調者的請求執行事務提交或回滾,並向協調者發送Ack消息協調者收到所有的Ack消息過後判斷事務的完成或者中斷該協議可以視為強一致的算法,通常用來保證多份數據操作的原子性,也可以實現數據副本之間的一致性
  • 用Python實現線性回歸,8種方法哪個最高效?
    另一方面,也是更為重要的一點,線性模型的易解釋性使得它在物理學、經濟學、商學等領域中佔據了難以取代的地位。如何用Python來實現線性回歸?由於機器學習庫scikit-learn的廣泛流行,常用的方法是從該庫中調用linear_model來擬合數據。
  • 8種用Python實現線性回歸的方法
    另一方面,也是更為重要的一點,線性模型的易解釋性使得它在物理學、經濟學、商學等領域中佔據了難以取代的地位。那麼,如何用Python來實現線性回歸呢?由於機器學習庫scikit-learn的廣泛流行,常用的方法是從該庫中調用linear_model來擬合數據。
  • 面試官:聊聊 etcd 中的 Raft 吧
    Raft:https://en.wikipedia.org/wiki/Raft_(computer_science "Raft") 是近年來比較流行的一個一致性算法。它的原理比較容易理解,網上也有很多相關的介紹,因此這裡我就不再囉嗦原理了,而是打算以 raft 在 etcd 中的實現1[1]為例,從工程的角度來講講這個算法的一個具體實現,畢竟了解原理只算是「紙上談兵」,離真正能把它應用起來還有很長一段距離。
  • 美國網站伺服器性能優化的方法
    提高美國網站伺服器的性能,以最大限度的利用率實現利益的最大化,這是很多美國網站伺服器用戶所希望達到的效果,因此美國網站伺服器的的性能優化是非常重要且必要的工作。今天小編就來分享下美國網站伺服器性能優化的方法。