有效個數(Quorum)這個設計模式通常是指分佈式系統的每一次修改都要在大多數實例上經過來肯定修改經過。編程
在一個分佈式存儲系統中,用戶請求會發到一個實例上。一般在一個實例上面執行的修改,須要複製到其餘的實例上,這樣能夠保證在原實例掛了的狀況下,用戶依然能夠看到這個修改。這就涉及到一個問題,究竟複製到多少個其餘實例上以後,用戶請求才會返回成功呢?若是複製的實例個數過多,那麼請求響應時間就會更長;若是複製的實例過少,則這個修改可能會丟失。取得這個平衡性很重要,這也是分佈式 PACELC 中的 L(Latency) 與 C(Consistency) 的取捨。設計模式
當一個修改,被集羣中的大部分節點(假設個數爲N)經過以後,這個修改也就被這個集羣所接受。這個 N 就是有效個數。假設集羣數量爲 n,那麼 N = n/2 + 1.例如 n = 5,則 N = 3.微信
這個有效個數,間接地體現了集羣中最多能夠有多少個實例掛掉,這個數量就是 f = n - N。一般的,若是咱們指望能夠忍受 f 個實例掛掉,那麼集羣就至少要有 2f + 1 個實例。併發
如下就是兩個經典須要有效個數這個設計模式的場景:異步
目前主流的集羣設計模式有以下兩種:分佈式
在這種設計模式下的系統,主要考慮兩點:ide
客戶端把寫請求發送到 leader 節點上(若是發送的是 follower 節點,follower節點會把寫請求轉發到leader節點),leader節點會把數據經過proposal請求發送到全部節點(包括本身),全部到節點接受到數據之後都會寫到本身到本地磁盤上面,寫好了之後會發送一個ack請求給leader,leader只要接受到過半的節點發送ack響應回來,就會發送commit消息給各個節點,各個節點就會把消息放入到內存中(放內存是爲了保證高性能),該消息就會用戶可見了。函數
在默認狀況下,是 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的時候,其實是向三個節點同時發了讀請求,要三個節點都返回結果才能認爲成功。假設某個節點的響應很慢,它就會嚴重拖累一個讀操做的響應速度性能
MongoDB 和上面的 Dynamo 相似,MongoDB關於一致性、可用性的權衡,取決於三者: 設計
write-concern
: 表示當寫請求在value個MongoDB實例處理以後才向客戶端返回read-concern
: 設定是否必須從 primary 讀取最新的數據仍是能夠從 secondary 讀取最終一致性的數據。read-preference
: 對於replica set,是返回當前節點的最新數據,仍是返回寫入節點最多的數據,仍是根據一些函數計算出的數據。微信搜索「個人編程喵」關注公衆號,每日一刷,輕鬆提高技術,斬獲各類offer: