2021-2-16:請問你知道分佈式設計模式中的Quorum思想麼?

有效個數(Quorum)

有效個數(Quorum)這個設計模式通常是指分佈式系統的每一次修改都要在大多數實例上經過來肯定修改經過。編程

問題背景

在一個分佈式存儲系統中,用戶請求會發到一個實例上。一般在一個實例上面執行的修改,須要複製到其餘的實例上,這樣能夠保證在原實例掛了的狀況下,用戶依然能夠看到這個修改。這就涉及到一個問題,究竟複製到多少個其餘實例上以後,用戶請求才會返回成功呢?若是複製的實例個數過多,那麼請求響應時間就會更長;若是複製的實例過少,則這個修改可能會丟失。取得這個平衡性很重要,這也是分佈式 PACELC 中的 L(Latency) 與 C(Consistency) 的取捨。設計模式

解決方案

當一個修改,被集羣中的大部分節點(假設個數爲N)經過以後,這個修改也就被這個集羣所接受。這個 N 就是有效個數。假設集羣數量爲 n,那麼 N = n/2 + 1.例如 n = 5,則 N = 3.微信

這個有效個數,間接地體現了集羣中最多能夠有多少個實例掛掉,這個數量就是 f = n - N。一般的,若是咱們指望能夠忍受 f 個實例掛掉,那麼集羣就至少要有 2f + 1 個實例。併發

如下就是兩個經典須要有效個數這個設計模式的場景:異步

  • 更新存儲集羣中的數據。同時還會涉及到最高水位線(High-Water Mark)這個設計模式,用於標註截止到哪裏的日誌,已經同步到了集羣中的大多數實例。
  • 選主。在主從(Leader and)設計模式中,被有效個數選舉爲主的就是最終的主。

如何設計集羣個數

目前主流的集羣設計模式有以下兩種:分佈式

image

  • 第一種是主從同步模式:
    • 一種是請求發往主,主負責同步到其餘從上面,以後返回。若是請求發到了從上面,則從發到主上面處理。例如 Zookeeper 就是這麼作的。
    • 另外一種是,請求發到哪一個實例,哪一個實例就是主,主將請求同步到從上面。例如 Eureka 就是這麼設計的。
  • 第二種是分區模式,集羣中不一樣節點存儲不一樣數據。通常的,這個數據切分常常採用一致性哈希。假設請求發送到了 A,通過 A 的計算,這個數據須要存儲在 D,而且咱們配置的存儲備份是一份,這個備份是在 E 上面,這樣這個請求就會被同步到 D,E 上面。ElasticSearch,Riak,Dynamo 就是這種相似的設計。

在這種設計模式下的系統,主要考慮兩點:ide

  • 寫操做的吞吐量。由於每次寫入集羣,都要複製到多個實例,因此確定會對性能有所影響。通常的,複製是併發複製的,這個性能主要受本次同步最慢的那個實例的影響。
  • 能夠容忍的實例掛掉的個數。這樣的集羣,若是咱們指望能夠忍受 f 個實例掛掉,那麼集羣就至少要有 2f + 1 個實例。

實現舉例

1. Zookeeper 的兩階段提交 + 半數以上寫入機制

客戶端把寫請求發送到 leader 節點上(若是發送的是 follower 節點,follower節點會把寫請求轉發到leader節點),leader節點會把數據經過proposal請求發送到全部節點(包括本身),全部到節點接受到數據之後都會寫到本身到本地磁盤上面,寫好了之後會發送一個ack請求給leader,leader只要接受到過半的節點發送ack響應回來,就會發送commit消息給各個節點,各個節點就會把消息放入到內存中(放內存是爲了保證高性能),該消息就會用戶可見了。函數

2. Riak,DynamoDB

默認狀況下,是 P+A 以及 E+L 的系統,可是能夠根據配置修改,主要基於NWR模型與同步和異步備份。N 表明 N 個備份,W 表明要寫入至少 W 份才認爲成功,R 表示至少讀取 R 個備份。配置的時候要求 W+R > N。 由於 W+R > N, 因此 R > N-W。這個是什麼意思呢?就是讀取的份數必定要比總備份數減去確保寫成功的倍數的差值要大。
也就是說,每次讀取,都至少讀取到一個最新的版本。從而不會讀到一份舊數據。當咱們須要高可寫的環境的時候(例如,amazon 的購物車的添加請求應該是永遠不被拒絕的)咱們能夠配置W = 1 若是N=3 那麼R = 3。 這個時候只要寫任何節點成功就認爲成功,可是讀的時候必須從全部的節點都讀出數據。若是咱們要求讀的高效率,咱們能夠配置 W=N R=1。這個時候任何一個節點讀成功就認爲成功,可是寫的時候必須寫全部三個節點成功才認爲成功。
你們注意,一個操做的耗時是幾個並行操做中最慢一個的耗時。好比R=3的時候,其實是向三個節點同時發了讀請求,要三個節點都返回結果才能認爲成功。假設某個節點的響應很慢,它就會嚴重拖累一個讀操做的響應速度性能

3. MongoDB

MongoDB 和上面的 Dynamo 相似,MongoDB關於一致性、可用性的權衡,取決於三者: 設計

  • write-concern: 表示當寫請求在value個MongoDB實例處理以後才向客戶端返回
  • read-concern: 設定是否必須從 primary 讀取最新的數據仍是能夠從 secondary 讀取最終一致性的數據。
  • read-preference: 對於replica set,是返回當前節點的最新數據,仍是返回寫入節點最多的數據,仍是根據一些函數計算出的數據。

微信搜索「個人編程喵」關注公衆號,每日一刷,輕鬆提高技術,斬獲各類offer:

image

相關文章
相關標籤/搜索