天天看點

NWR模型版本沖突問題簡述NWR模型髒資料引入版本版本沖突問題

簡述NWR模型

所謂NWR模型。N代表N個備份,W代表要寫入至少W份才認為成功,R表示至少讀取R個備份。配置的時候要求W+R > N。 因為W+R > N, 是以 R > N-W 這個是什麼意思呢?就是讀取的份數一定要比總備份數減去確定寫成功的倍數的內插補點要大。也就是說,每次讀取,都至少讀取到一個最新的版本。進而不會讀到一份舊資料。

  1. 當我們需要高可寫的環境的時候,我們可以配置W = 1 如果N=3 那麼R = 3。 這個時候隻要寫任何節點成功就認為成功,但是讀的時候必須從所有的節點都讀出資料。
  2. 如果我們要求讀的高效率,我們可以配置 W=N R=1。這個時候任何一個節點讀成功就認為成功,但是寫的時候必須寫所有三個節點成功才認為成功。

髒資料

NWR模型的一些設定會造成髒資料的問題,因為這很明顯不是像Paxos一樣是一個強一緻的東西,是以,可能每次的讀寫操作都不在同一個結點上,于是會出現一些結點上的資料并不是最新版本,但卻進行了最新的操作。

引入版本

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

版本沖突問題

  • 比如:我們設定了N=3 W=1,如果A結點上接受了一個值,版本由v1 -> v2,但還沒有來得及同步到結點B上(異步的,應該W=1,寫一份就算成功),B結點上還是v1版本,此時,B結點接到寫請求,按道理來說,他需要拒絕掉,但是他一方面并不知道别的結點已經被更新到v2,另一方面他也無法拒絕,因為W=1,是以寫一分就成功了。于是,出現了嚴重的版本沖突。

Vector Clock

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是明顯的版本沖突。于是,交給調用方自己去做版本沖突處理。就像源代碼版本管理一樣。

繼續閱讀