分佈式系統基礎總結

一直在搞分佈式系統,Hadoop, Spark, Kafka, ZooKeeper之類的都玩過,然而之前只是簡單地用用各個開源組件實現,並無系統地學習其中的原理和算法。最近在跟着MIT 6.824課程學習分佈式系統的各類理論原理,這裏就來簡單總結下分佈式系統中的一些基礎內容吧~git

CAP Theory

CAP Theory闡述了分佈式系統中的一個事實:一致性(Consistency)、可用性(Availability)和分區容錯性(Partition Tolerance)不能同時保證。三個只能選擇兩個算法

CAP Theory

假設有兩臺機器A、B,二者之間互相同步保持數據的一致性。如今B因爲網絡緣由不能與A通訊(Network Partition),假設某個client向A寫入數據,如今有兩種選擇:服務器

  • A拒絕寫入,這樣能保證與B的一致性,可是犧牲了可用性
  • A容許寫入,可是這樣就不能保證與B的一致性了

Network Partition是必然的,網絡很是可能出現問題(斷線、超時),所以CAP理論通常只能AP或CP,而CA通常較難實現。網絡

  • CP: 要實現一致性,則須要必定的一致性算法,通常是基於多數派表決的,如Paxos和Raft
  • AP: 要實現可用性,則要有必定的策略決議到底用哪一個數據,而且數據通常要進行冗餘備份(replication)

固然,在上面的例子中,A能夠先容許寫入,等B的網絡恢復之後再同步至B(根據CAP原理這樣不能保證強一致性了,可是能夠考慮實現最終一致性)。架構

一致性哈希

分佈式Key-Value Store中的key映射問題。併發

  • 傳統hash(x) % N算法的弊端:不利於架構的伸縮性
  • 一致性哈希將哈希值映射到一個哈希環上,而後將數據進行哈希處理後映射到哈希環上,再把節點進行哈希處理映射到哈希環上,數據將選擇最近的節點存儲
  • 伸縮性:節點刪除時,原有的數據將會就近遷移,其餘數據不用遷移;節點增長時也類似
  • 保證負載均衡:虛擬節點

拜占庭將軍問題

最複雜的狀況:本身發的包被截;對方發的包本身收不到;內部有節點搗亂,形成不一致。負載均衡

FLP Impossibility

Impossibility of Distributed Consensus with One Faulty Process 這篇論文提到:異步

No completely asynchronous consensus protocol can tolerate even a single unannounced process death.async

假設節點只有崩潰這一種異常行爲,網絡是可靠的,而且不考慮異步通訊下的時序差別。FLP Impossibility指出在異步網絡環境中只要有一個故障節點, 任何Consensus算法都沒法保證行爲正確。分佈式

Lease機制

Lease(租約)機制應用很是普遍:

  • 可用做受權來進行同步等操做(如Append)
  • 可用做讀鎖/寫鎖(分佈式鎖)

租約的一個關鍵點就是有效期,過了有效期能夠續約。若是不可用就收回租約,給另外一臺服務器權限。

實際應用:

  • GFS: Master grant to ChunckServer

思考:Lease == Lock?

Quorum機制

多數表決機制在分佈式系統中一般有兩個應用場景:

  1. Leader Election
  2. Replication (NWR機制)

理論基礎:鴿巢原理

Consensus問題

Consensus條件

  • Termination: 最終必須決議出結果
  • Validity:
  • Integrity
  • Agreement

2PC/3PC

2PC在proposer和某個voter都掛掉的時候會阻塞(緣由:別的節點沒有對應voter的消息,只能阻塞等待此voter恢復)

3PC添加了一個 prepare-commit 階段用於準備提交工做,這裏面能夠實現事務的回滾。

缺點:效率貌似很低。。。分佈式事務用2PC會特別蛋疼

Paxos

推演:

  • First Accept/Last Accept都不能夠(結合時序圖)
  • 一個階段不行,天然想到兩個階段:發起決議以及提交決議
  • One Proposer -> One Acceptor 掛了就gg了
  • One Proposer -> Many Acceptors (規則:先到先投)
  • Many Proposers -> Many Acceptors (很容易亂。。。)

Paxos引入了Log ID (num, value),共有三個角色,兩個階段。

  • Proposer: 決議發起者,須要等待多數派表決
  • Acceptor: 決議投票者,對收到的Propose進行表決並返回
  • Learner: 最水的角色,學習到投票的結果便可

分佈式一致性算法(Paxos, Raft, Chubby, Zab)待詳細總結。。。

時序問題

Lamport Timestamp

通常咱們不關心分佈式系統中某個過程的絕對時間,而只關注兩個事件之間的相對時間。
在一個系統的事件集合E上定義一種偏序關係->,知足:

  • 若是a與b發生在同一個進程中,且a先於b發生,則有a -> b
  • 進程間通訊,a表明進程Pi發出消息m,b表明另外一個進程Pj接收消息m,則有a -> b
  • 傳遞性:若a -> b, b -> c,則a -> c

定義併發:a -> bb -> a均不成立則爲併發狀況

引入Lamport邏輯時鐘。一個時鐘本質上是一個事件到實數的映射(假設時間是連續的)。對於每個進程Pi,都有其對應的時鐘Ci。

分佈式系統中的全局信息其實是對各個實體信息的疊加(Q:重合怎麼辦?)

能夠看到Lamport Timestamp必需要求兩個事件有前後順序關係,於是在時序圖上很差表示concurrent。由此引入Vector Clock。

Vector Clock

Vector Clock是對Lamport Timestamp的演進。它不只保存了自身的timestamp,並且還保留了根節點的timestamp。

Vector Clock(Version Vector)只能用於發現數據衝突,可是想要解決數據衝突還要留給用戶去定奪(就比如git commit出現conflicts,須要手工解決同樣),固然也能夠設置某種策略來直接解決衝突(保留最新或集羣內多數表決)。

結合時序圖理解會更好(圖來自維基百科):

可能出現的問題:Vector Clock過多。解決方案:剪枝(若是超過某個閾值就把最初的那個給扔掉;要是如今還依賴最初的那個clock的話可能就會形成一些問題(思考:如何解決?)

相關文章
相關標籤/搜索