NWR模型[轉載]

NWR模型把CAP的選擇權交給了用戶,讓用戶自己的選擇你的CAP中的哪兩個

 

所謂NWR模型。N代表N個備份,W代表要寫入至少W份才認爲成功,R表示至少讀取R個備份。配置的時候要求W+R > N。 因爲W+R > N, 所以 R > N-W 這個是什麼意思呢?就是讀取的份數一定要比總備份數減去確保寫成功的倍數的差值要大。

也就是說,每次讀取,都至少讀取到一個最新的版本。從而不會讀到一份舊數據。當我們需要高可寫的環境的時候,我們可以配置W = 1 如果N=3 那麼R = 3。 這個時候只要寫任何節點成功就認爲成功,但是讀的時候必須從所有的節點都讀出數據。如果我們要求讀的高效率,我們可以配置 W=N R=1。這個時候任何一個節點讀成功就認爲成功,但是寫的時候必須寫所有三個節點成功才認爲成功。

NWR模型的一些設置會造成髒數據的問題,因爲這很明顯不是像Paxos一樣是一個強一致的東西,所以,可能每次的讀寫操作都不在同一個結點上,於是會出現一些結點上的數據並不是最新版本,但卻進行了最新的操作。

所以,Amazon Dynamo引了數據版本的設計。也就是說,如果你讀出來數據的版本是v1,當你計算完成後要回填數據後,卻發現數據的版本號已經被人更新成了v2,那麼服務器就會拒絕你。版本這個事就像“樂觀鎖”一樣。

但是,對於分佈式和NWR模型來說,版本也會有惡夢的時候——就是版本衝的問題,比如:我們設置了N=3 W=1,如果A結點上接受了一個值,版本由v1 -> v2,但還沒有來得及同步到結點B上(異步的,應該W=1,寫一份就算成功),B結點上還是v1版本,此時,B結點接到寫請求,按道理來說,他需要拒絕掉,但是他一方面並不知道別的結點已經被更新到v2,另一方面他也無法拒絕,因爲W=1,所以寫一分就成功了。於是,出現了嚴重的版本衝突。

Amazon的Dynamo把版本衝突這個問題巧妙地迴避掉了——版本衝這個事交給用戶自己來處理。

於是,Dynamo引入了Vector Clock(矢量鍾?!)這個設計。這個設計讓每個結點各自記錄自己的版本信息,也就是說,對於同一個數據,需要記錄兩個事:1)誰更新的我,2)我的版本號是什麼。

下面,我們來看一個操作序列:

1)一個寫請求,第一次被節點A處理了。節點A會增加一個版本信息(A,1)。我們把這個時候的數據記做D1(A,1)。 然後另外一個對同樣key的請求還是被A處理了於是有D2(A,2)。這個時候,D2是可以覆蓋D1的,不會有衝突產生。

2)現在我們假設D2傳播到了所有節點(B和C),B和C收到的數據不是從客戶產生的,而是別人複製給他們的,所以他們不產生新的版本信息,所以現在B和C所持有的數據還是D2(A,2)。於是A,B,C上的數據及其版本號都是一樣的。

3)如果我們有一個新的寫請求到了B結點上,於是B結點生成數據D3(A,2; B,1),意思是:數據D全局版本號爲3,A升了兩新,B升了一次。這不就是所謂的代碼版本的log麼?

4)如果D3沒有傳播到C的時候又一個請求被C處理了,於是,以C結點上的數據是D4(A,2; C,1)。

5)好,最精彩的事情來了:如果這個時候來了一個讀請求,我們要記得,我們的W=1 那麼R=N=3,所以R會從所有三個節點上讀,此時,他會讀到三個版本:

    • A結點:D2(A,2)
    • B結點:D3(A,2;  B,1);
    • C結點:D4(A,2;  C,1)

6)這個時候可以判斷出,D2已經是舊版本(已經包含在D3/D4中),可以捨棄。

7)但是D3和D4是明顯的版本衝突。於是,交給調用方自己去做版本衝突處理。就像源代碼版本管理一樣。

很明顯,上述的Dynamo的配置用的是CAP裏的A和P。

我非常推大家都去看看這篇論文:《Dynamo:Amazon’s Highly Available Key-Value Store》,如果英文痛苦,你可以看看譯文(譯者不詳)

發佈了151 篇原創文章 · 獲贊 3 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章