1. 程式人生 > >帶著問題學習分散式系統之中心化複製集

帶著問題學習分散式系統之中心化複製集

  假若我說有三個節點(計算機)要維護同一分資料,如果你對分散式系統並不瞭解,那麼你可能會有什麼問題呢,我想可能有兩個最基本的問題:

  1.   為什麼同一份資料要儲存多分?
  2.   這些節點資料要一致吧,否則同時從多個節點讀的時候資料不一樣?

  第一個問題,為什麼要同一分資料要儲存多分,是因為分散式系統中的節點都有一定的概率發生故障,雖然單個節點的故障概率比較小,但當系統規模不斷上升,故障的概率就變大了許多。節點的故障會對系統的可用性、可靠性產生影響。當資料在系統中只有一份儲存時,如果發生斷電、主機crash、網路故障,那麼導致的是資料的暫時不可用;如果發生磁碟損壞,則會導致資料丟失,也就是系統不可靠。因此資料冗餘(複製集、副本集),即同一分資料在系統中不同節點儲存多分,可以有效提高系統的可用性和資料的可靠性。當然,資料冗餘也有一些缺點,比如佔用額外的頻寬和儲存資源。

  第二個問題一下就命中了複製集的要害,也是分散式系統中對複雜的問題之一: 副本的一致性問題,即從系統外部讀取系統內部各個副本間的資料在一定的約束條件下是一致的。在這篇文章中介紹過CAP理論,即對於分散式資料儲存,最多隻能同時滿足一致性(C,Consistency)、可用性(A, Availability)、分割槽容錯性(P,Partition Tolerance)中的兩者。而分散式系統中網路分割一定是存在的,所以CAP -- “it is really  just A vs C!"

  同時必須注意的是,A和C都是一個度的問題,而不是0和1兩個極端,因此可以在滿足一定的可用性同時保證一定的一致性。不同的需求決定了到底是一致性重要還是可用性更重要,比如在購物網站中,可用性非常重要,分分鐘的不可訪問都會帶來巨大損失;而在《

帶著問題學習分散式系統之資料分片》中提到的元資料管理,一致性就非常重要,不然就亂套了。

  為了解決第二個問題,人們提出了很多不同的副本控制協議,即在分散式系統中,按照特定的流程規範來讀寫副本資料,使得副本滿足一定的可用性和一致性的要求。

  副本控制協議有很多,也有不同的分類標準,比如:同步與非同步、強一致性與弱一致性、中心化與去中心化。本文主要介紹中心化副本控制協議,在講解不同的系統實現時,也分提到在同步與非同步、強一致性與弱一致性方面的選擇。

中心化副本控制協議

  所謂的中心化,就是對於副本集的更新操作有一箇中心節點來協調管理,將分散式的併發操作轉化為單點的併發操作,從而保證副本集內各節點的一致性。其優點在於邏輯簡單,將複雜的問題(分散式併發)轉換成一個有成熟解決方案的問題(單點併發)。但缺點在於,副本集的可用性依賴於中心節點,如果中心節點故障,即使有中心節點自動切換機制,也會出現數10秒的不可用。

  

  大多數的分散式儲存都會採用中心化副本控制協議,比如GFS,TFS,MongoDB

  而去中心化則是說副本集中沒有中心節點,所有節點的地位是平等的,大家都可以接受更新請求,相互通過協商達成資料的一致。去中心化副本控制協議的最大好處在於可用性比較強,只要有大多數節點存活就能提供服務。但缺點時協議流程複雜,尤其是需要強一致性保證的時候。

  在業界中,Dynamo,cassandra就是基於去中心化協議,雖然 Dynamo 嘗試通過引入 Quorum 機制和 vector clock 機制解決讀取資料的一致性問題,但其一致性模型依舊是一個較大的問題。

  本文主要對中心化副本控制協議進行詳細介紹。

  中心化副本控制協議在分散式儲存系統中使用非常規範,但各家實現又有不同。這裡主要集合分散式檔案系統與分散式資料庫來做對比分析

  回顧《帶著問題學習分散式系統》一文,對於中心化副本控制協議,提出了以下疑問,本章節試圖給出解答。

  (3.1)寫節點怎麼將變更的資料同步到其他節點,同步還是非同步;

  (3.2)非寫節點能否提供讀資料,如果能夠允許,會不會讀取到過時的資料。   (3.3)主節點是怎麼產生的,當主節點宕機的時候,怎麼選擇出新的主節點。是有統一的複製集管理中心(記錄誰主誰次,各自的狀態),還是複製集自己選舉出一個主節點?

主從節點資料更新流程

  第一個問題:複製集之間資料的同步是同步模式還是非同步模式。

  在中心化副本控制協議中,主節點(primary)提供寫入操作,資料會同步到其他節點。注意,上面語句中第一個同步是指複製集中節點間資料趨於一致的過程。

  所謂同步(Synchronous replication),就是說對於客戶端請求,系統阻塞到複製集中所有節點都更新完成,才能向客戶端返回,即write all。而非同步(Asynchronous replication)模式,只要一個或者部分節點更新則算寫入操作成功,通常是write one。

    

  上圖(來源於Distributed systems for fun and profit,下同)即為同步模式,客戶端的請求被髮送到s1這個副本集,s1將請求轉發給s2、s3,等s2、s3都操作完成之後再向客戶端返回結果。

  在同步模式下,系統的可靠性非常好,只要有一個節點正常,就能保證資料不丟失。但是系統的更新可用性非常差,只要有一個節點異常,就無法完成更新;而且,響應延遲比較大,取決於副本集中網路延時最大、處理速度最慢的節點。

    

  上圖則是非同步模式,客戶端的寫請求只要在一個節點上完成就立即向客戶端返回結果。在上圖中,資料被寫入到s1即認為寫入成功,向客戶端返回,系統在後臺由s1向s2、s3節點同步資料。

  非同步模式下,系統的吞吐量會比較好,但是存在資料丟失的風險,比如上圖中,如果在資料同步到s2 s3之前s1掛掉,那麼剛才客戶端的更新就丟失了,關鍵在於客戶端認為已經寫入成功了。另外,非同步模式下,客戶端在寫入成功之後,立刻從系統讀取資料,有可能讀不到最新的資料,比如上圖中,客戶端寫入s1之後立刻從s2 讀取。

  在資料同步的時候選擇同步模式還是非同步模式呢,這個取決於系統對一致性、可用性、響應延遲的要求。

  比如在分散式檔案系統GFS中,需要保證複製集內副本的強一致性,而單次讀寫的響應延遲並沒有那麼重要,因此選擇了同步模式,即primary需要等到所有的secondary都寫入成功才會向客戶端返回。

  而在分散式資料庫MongoDB中,決定權交給了使用者,使用者可以決定使用同步模式還是非同步模式。在《CAP理論與MongoDB一致性、可用性的一些思考》一文中詳細介紹了writeconcern這個寫入選項。如果w:1.那麼只會寫入到primary節點就立即返回,系統會在後臺向secondary節點同步資料,即為非同步模式。如果w:N(N為複製集節點數目),那麼primary節點需要等到所有secondary都更新到最新的資料之後(或者等待超時)才向客戶端返回,也就是同步模式。即使在去中心化副本控制協議,如cassandra,也提供給使用者自行設定一致性等級。

  前面已經提到了同步模式、非同步模式各自的優劣,這裡以MongoDB為例具體討論,看看同步、非同步模式對系統一致性、可用性的影響。

  在非同步模式(w: 1)下,系統的響應延遲很低,可用性非常好,但存在兩個問題。第一:同一個客戶端在得到成功寫入的返回之後立即從secondary節點讀取,有可能讀不到最新的資料;第二:在主從切換的時候(後面會詳細講解這一過程),可能發生rollback,簡單來說,資料只持久化到了primary,secondary節點還未更新到最新的資料,此時如果primary故障,系統會選舉出新的primary,即使舊的primary恢復正常後以secondary身份重新加入複製集,新的primary不會承認其資料,這就導致了更新丟失的問題。

  同步模式下(w:N或者w:Majority),需要等待所有節點都寫入成功,響應延遲會比較高,在資料庫應用中一般很難接受,之前基於《通過一步步建立sharded cluster來認識MongoDB》中的複製集(一個primary、一個secondary、一個arbiter)做過實驗,如果將secondary shutdown(db.shutdownServer),然後用writeConcern: {w: "majority”, wtimeout: 10}寫入資料,客戶端會阻塞到超時,然後給出超時資訊。不過,w:majority保證了寫入的資料不會丟失,即不會出現rollback的問題。

  第二個問題:資料的流向

  即資料是如何從Primary節點到secondary節點的。

  首先是比較有意思的GFS,GFS寫入流程如下:

  

  GFS的寫入將控制流與資料流分開,客戶端會把資料流鏈式推送到各個節點,推送的過程並不關心誰是primary、誰是secondary。需要注意的是,各節點(GFS中稱之為chunkserver)只是快取資料,等到Primary向secondary傳送持久換指令(step5)的時候再回真正持久化寫入。

  更一般的,資料的流向有兩種,鏈式與主從模式。

  鏈式就是指從一個節點推送到最近的節點,比如GFS,“最近” 可以用IP地址或者節點間心跳TTL來衡量,如圖所示(圖片來源於清華阿里-大資料課程的PPT):

  

  不難看出,寫入過程中每個節點的頻寬利用都比較均衡,可以充分利用網路資源,也不會有單點壓力;但是需要經過多個節點,寫入延遲會比較大。

  而主從模式則是指資料同時從primary節點到secondary節點,如圖所示(來源

  

  預設情況下MongoDB也是採用的鏈式模式,但是可以通過設定 採用主從模式。在主從模式下,Secondary會從Primary拉取OPLOG並應用到本地。顯然,在這種模式下Primary節點的頻寬壓力比較大,但是寫入延遲會小一些。

  第三個問題:部分節點寫入失敗了怎麼辦

  不管是同步模式還是非同步模式,也不管是鏈式推送還是主從模式推送,複製集中資料的寫入都是1PC(1 phase commit)。即資料的更新只有一個commit階段,而沒有prepare階段,如果某些節點發生故障,那麼提交在故障節點上會失敗,甚至是提交了部分、不完整的資料。

  複製集中多個節點的更新本質上來說應該是分散式事務問題,理論上應該保證原子行:要麼都更新成功,要麼都不更新,而不會出現部分節點更新成功的情況。但經典解決方案如兩階段提交代價太大,因此分散式儲存中的複製集更新大多采用best effort 1pc,只不過不同的系統對更新失敗的處理有所區別。

  比如MongoDB,以第一個問題中提到的例子,writeconcern為w: majority,由於其中一個secondary掛掉,寫入操作是不可能成功的。因此,在超時時間到達之後,會向客戶端返回出錯資訊。但是在這個時候直接連線到rs的primary節點,資料是持久化到了primary節點,不會被回滾。

  另外,對於分散式圖片儲存haystack,如果更新失敗,會重試流程,直到成功或超時,重試的話所有節點都會重試。那麼可能出現兩個問題,某個節點上資料部分寫入(寫入部分資料就崩潰了);由於重試是對複製集中所有節點重試,因此某個節點上同一份資料可能寫入了多份。對於第一個問題,由於有checksum,因此不怕部分寫入失敗;第二個問題,由於有offset和元資料,重複寫入也不是問題。haystack(以及GFS)通過這種巧妙的方式解決了分散式更新問題。

主從節點資料讀取

  複製集中,不同的系統在資料讀取方面有兩個問題。第一:secondary節點是否提供讀服務;第二,如果可以從Secondary讀取,那麼這個介面是否開放給使用者

  第一個問題,如果secondary節點提供資料讀取服務,那麼是否會讀取到過期的資料(即不是最新成功寫入的資料) ?比如在非同步寫入的時候,客戶端得到成功寫入的返回之後,立即去secondary上讀取,那麼有可能讀到過時的資料,這對於強一致性的情況是不能允許的。我們知道,元資料的管理一般也是複製集,而元資料需要保證強一致性,因此,元資料的寫入一般都是同步的。比如GFS中,master由一個active(也就是primary節點)、多個standby(也就是secondary節點)組成,在元資料寫入到active的時候,要保證本地和遠端機器都寫入成功才能返回;而且只有active提供讀取服務。

  第二個問題,如果複製集中的節點都能提供讀取服務,那麼介面是否提供給終端使用者呢?在haystack中,多個在不同機器上的物理卷組成一個邏輯卷,一個邏輯卷就是一個複製集。當讀取請求到達的時候,是由haystack的元資料伺服器(directory)根據負載均衡的原則選出提供服務的物理卷,即使用者是不知道讀取請求是落地到哪個物理節點的。而對於mongodb,使用者可以在查詢語句裡面指定是從Primary讀取,還是從Secondary讀取,或者讓系統來選擇(Nearest)。

  讀取方式與使用者角度的一致性非常相關,比如在MongoDB中,不同的readrefence導致一致性、可用性的差異,具體可見《CAP理論與MongoDB一致性、可用性的一些思考

主節點選舉

  在中心化副本控制協議中,這個中心(primary)是怎麼選出來的呢?是上級指定還是民主選舉呢?

  GFS系統中,Primary節點是由master(GFS中的元資料伺服器)通過lease機制選擇的,關於Lease機制的,可以參見《帶著問題學習分散式系統之資料分片》一文中相關章節的介紹。簡單說來,GFS給某個節點頒發Lease,該節點就成為了Primary節點,Primary節點也可以在過期之前重新申請Lease,而且Lease的頒發、申請資訊都是在chunkserver與master的心跳中,因此也不會帶來過多額外的開銷。使用Lease機制能很好的避免在複製集中出現雙主(同時有兩個節點認為自己是Primary)現象。

  而在Zookeeper、TFS、MongoDB中,都是通過去中心化的協議選舉出Primary節點,選舉出Primary節點之後,就變成了中心化的副本控制協議,當Primary出現故障之後,會重新選舉過程。對於民主選舉,兩個因素非常重要:第一是強一致性,只能選舉出一個Primary;第二個是可用性,選舉過程要越快越好。

  為了達到強一致性,需要使用分散式一致性協議,目前較為常見的協議有Paxos協議,該協議可以實現所有備份均可以提供對外服務,並且保證強一致性,通過理論和實踐檢驗可以達到分散式的要求。Raft協議則是Paxos的一種特化,在這個協議的實現中,備份間需要區分主從角色,只有主節點可以提供對外服務,協議實現簡單高效,能很容易的同各種分散式資料一致性同步場景相結合,是工程實現最好的選擇。

  在mongodb3.2中,Primary選舉演算法改成了raft-like演算法,此舉的目的也是為了縮短選舉的時間,具體可見Replica Set Protocol Version

  在TFS中,meta server(元資料伺服器)也是通過raft協議選舉primary的,下面兩個gif形象展示了primary初始選舉以及當primary故障之後的重新選舉(圖片來源於清華阿里-大資料課程的PPT)。

  

  上圖展示了Primary選舉過程

  

  上圖展示了在原來的Primary掛掉之後(也可能僅僅是失去響應),剩餘的節點是如何選舉出新的Primary。

  為了防止出現雙主的情況,在投票過程中至少要有超過半數的節點同意才能選出Primary,這也是為什麼複製集中節點數目都是奇數個的原因。

總結

  本文介紹了在分散式儲存領域使用得比較廣泛的中心化副本控制協議,通過不同的系統回答了在具體實現方便上的一些選擇。不過,對於具體的系統以及相關的協議,並沒有很深入介紹,感興趣的讀者可以查閱相關連結。

references

劉傑:分散式原理介紹

相關推薦

問題學習分散式系統中心複製

  假若我說有三個節點(計算機)要維護同一分資料,如果你對分散式系統並不瞭解,那麼你可能會有什麼問題呢,我想可能有兩個最基本的問題:   為什麼同一份資料要儲存多分?   這些節點資料要一致吧,否則同時從多個節點讀的時候資料不一樣?   第一個問題,為什麼要同一分資料要儲存多分,是因為分散式系統

問題學習分散式系統資料分片

  在前文中,提出了分散式系統(尤其是分散式儲存系統)需要解決的兩個最主要的問題,即資料分片和資料冗餘,下面這個圖片(來源)形象生動的解釋了其概念和區別:      其中資料即A、B屬於資料分片,原始資料被拆分成兩個正交子集分佈在兩個節點上。而資料集C屬於資料冗餘,同一份完整的資料在兩個節點都有儲存。當然

問題學習分散式系統

  很長一段時間,對分散式系統都比較感興趣,也聽說過、瞭解過其中一些相關的知識點,但都比較零碎。一直想系統的學習一下,但是一拖再拖,寫下本文,也是希望能督促自己。 寫在前面   聽過很多道理,卻依然過不好這一生。   看過很多關於學習的技巧、方法,卻沒應用到自己的學習中。   隨著年紀變大,記

機器學習:樣本去中心目的

idt rac 相同 orm ans 預處理 特征 original 需要 作者:Spark鏈接:https://www.zhihu.com/question/37069477/answer/132387124來源:知乎著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉

學習分散式系統,這些術語你瞭解嗎?

對於剛進入區塊鏈行業的小白同學來說,一切都顯得比較陌生,很多概念性質的東西理解起來也比較吃力,本文和大家分享的是區塊鏈分散式系統中常見的一些專業分類,一起來看看吧,希望對大家有所幫助。 1. Failure models 失效模型 機器故障:當機器(節點)出現故障時,共識協議就用於解決機器

分散式通訊序列

知識點: 1)序列化概念 2)實現序列化手段 3)序列化實現深克隆 4)主流序列化手段及操作 Java的序列化機制 Sericalize介面 存在的問題 1)序列化資料結果比較大 傳輸效率低 2)不能跨語言對接 後續xml編碼格式的物件序列化機制成為了主流。 1)多語言 2)便於理解 Json HTTP

分散式系統資料分片前言2

轉載:https://www.cnblogs.com/xybaby/p/7076731.html 目錄 三種資料分片方式 hash方式: 一致性hash  range based 小結: 分片特徵值的選擇

分散式系統資料分片前言1

轉載:https://www.cnblogs.com/xybaby/p/7076731.html 目錄 寫在前面 帶著問題出發 資料分片 資料冗餘 其他 總結: 正文   很長一段時間,對分散式系統都比較感興趣,也

什麼是分散式系統,如何學習分散式系統

目錄 正文   雖然本人在前面也寫過好幾篇分散式系統相關的文章,主要包括CAP理論、分散式儲存與分散式事務,但對於分散式系統,並沒有一個跟清晰的概念。分散式系統涉及到很多的技術、理論與協議,很多人也說,分散式系統是“入門容易,深入難”,我之前的學習也只算是管中窺豹

Ted 學習資料結構 二叉堆(Binary Heap)

二叉堆(Binary Heap) (1)structure property Heap(堆)是一個除了底層節點外的完全填滿的二叉樹,底層可以不完全,左到右填充節點。(a heap is a binar

[原創]分散式系統快取的微觀應用經驗談(三)【資料分片和叢集篇】

分散式系統之快取的微觀應用經驗談(三)【資料分片和叢集篇】 前言   近幾個月一直在忙些瑣事,幾乎年後都沒怎麼閒過。忙忙碌碌中就進入了2018年的秋天了,不得不感嘆時間總是如白駒過隙,也不知道收穫了什麼和失去了什麼。最近稍微休息,買了兩本與技術無關的書,其一是 Yann Martel 寫的《The

[原創]分散式系統快取的微觀應用經驗談(四) 【互動場景篇】

分散式系統之快取的微觀應用經驗談(四) 【互動場景篇】  前言   近幾個月一直在忙些瑣事,幾乎年後都沒怎麼閒過。忙忙碌碌中就進入了2018年的秋天了,不得不感嘆時間總是如白駒過隙,也不知道收穫了什麼和失去了什麼。最近稍微休息,買了兩本與技術無關的書,其一是 Yann Martel 寫的《The

分散式基礎序列與反序列

  目錄 序列化與反序列化,Why? 序列化的意義 一個簡單例項 JAVA序列化的高階認識 serialVersionUID 的作用 靜態變數序列化 父類的序列化 Transient 關鍵字 序列化的儲存規則 序列化實現深克隆 常見

[機器學習]推薦系統協同過濾演算法

在現今的推薦技術和演算法中,最被大家廣泛認可和採用的就是基於協同過濾的推薦方法。本文將帶你深入瞭解協同過濾的祕密。下面直接進入正題. 1. 什麼是推薦演算法 推薦演算法最早在1992年就提出來了,但是火起來實際上是最近這些年的事情,因為網際網路的爆發,有了更大的資料量可以供我們使用,推薦演算法才有了很大的用武

分散式系統CAP和BASE理論

CAP定理 一致性(Consistency) 在分散式環境中,一致性是指資料在多個副本之間是否能夠保持一致性的特性。 可用性(Availability) 可用性是指系統提供的服務必須一直處於可用的狀態,對於使用者的每一個操作請求總是能夠在有限的時間內返回結果。 分割

分散式系統資料分片及特徵值的選擇

正文   在前文中,提出了分散式系統(尤其是分散式儲存系統)需要解決的兩個最主要的問題,即資料分片和資料冗餘,下面這個圖片(來源)形象生動的解釋了其概念和區別:      其中資料即A、B屬於資料分片,原始資料被拆分成兩個正交子集分佈在兩個節點上。而資料集C屬於資料冗餘,同一份完整的資料

分散式系統分散式中介軟體zeroMQ

zeroMQ,又稱0MQ,是一個非常簡單的通訊庫,它擴充套件了傳統BSD socket能力,提供簡單的基於訊息的通訊。zeroMQ不解析訊息體,沒有序列化能力,或者說你可以使用任何第三方序列化庫比如google的protocol buffer。 iMatix公司,AMQP協

分散式系統Quorum (NRW)演算法

基於Quorum投票的冗餘控制演算法 Quorom 機制,是一種分散式系統中常用的,用來保證資料冗餘和最終一致性的投票演算法,其主要數學思想來源於鴿巢原理。 在有冗餘資料的分散式儲存系統當中,冗餘資料物件會在不同的機器之間存放多份拷貝。但是同一時刻一個數據物件的多份拷貝只能用於讀或者用於寫。 該演算法可

分散式系統五:程序/執行緒

本博文主要講訴核心作業系統的程序、執行緒等 程序     一個程序由一個執行環境和一個或多個執行緒組成。 執行環境:     資源管理的基本單位,它是一個程序的執行緒所能訪問的由本地核心管理的資源集合,可以提供保護而不被外部執行緒訪問。包含:     1. 一個地址空間:是一組虛擬記憶體的集合,由核心提供,

手把手你自制Linux系統六 編譯核心及busybox完成系統定製

手把手帶你自制Linux系統之六 編譯核心及busybox完成系統定製 重新看了一下前面的幾章,發現其實前面的5章一直圍繞一個話題講解 — 如何利用CentOS現有資源組裝一個Linux。這種方式十分拙劣,Linux核心是固化的、initrd沒有充分精簡、命令需要一個一個