分佈式系統的數據一致性

一、引言

數據一致性的重要性?

分佈式領域CAP理論告訴我們,任何一個分佈式系統都無法同時滿足Consistency(一致性),Availability(可用性), Partition tolerance(分區容錯性) 這三個基本需求。最多隻能滿足其中兩項。 但是,一個分佈式系統無論在CAP三者之間如何權衡,都無法徹底放棄一致性(Consistency),如果真的放棄一致性,那麼就說明這個系統中的數據根本不可信,數據也就沒有意義,那麼這個系統也就沒有任何價值可言。所以,無論如何,分佈式系統的一致性問題都需要重點關注。

由於一個分佈式系統不可能放棄一致性,那麼為什麼有的架構師還說在某些場景中可以犧牲一致性呢?通常這裡說的放棄一致性指的是放棄數據的強一致性。

通常情況下,我們所說的分佈式一致性問題通常指的是數據一致性問題。那麼我們就先來了解一下什麼是數據一致性。


分佈式系統的數據一致性


二、數據一致性

數據一致性其實是數據庫系統中的概念。我們可以簡單的把一致性理解為正確性或者完整性,那麼數據一致性通常指關聯數據之間的邏輯關係是否正確和完整。我們知道,在數據庫系統中通常用事務(訪問並可能更新數據庫中各種數據項的一個程序執行單元)來保證數據的一致性和完整性。而在分佈式系統中,數據一致性往往指的是由於數據的複製,不同數據節點中的數據內容是否完整並且相同。

​比如在集中式系統中,有一些關鍵的配置信息,可以直接保存在服務器的內存中,但是在分佈式系統中,如何保存這些配置信息,又如何保證所有機器上的配置信息都保持一致,又如何保證修改一個配置能夠把這次修改同步到所有機器中呢?

再比如,在集中式系統中,進行一個同步操作要寫同一個數據的時候,可以直接使用事務+鎖來管理保證數據的ACID。但是,在分佈式系統中如何保證多臺機器不會同時寫同一條數據呢?

三、為什麼會有數據一致性問題

雖然分佈式系統有著諸多優點,但是由於採用多機器進行分佈式部署的方式提供服務,必然存在著數據的複製。分佈式系統的數據複製需求主要來源於以下兩個原因:

1、可用性:將數據複製到分佈式部署的多臺機器中,可以消除單點故障。防止系統由於某些機器宕機導致的不可用。

2、性能:通過負載均衡技術,能夠讓分佈在不同地方的數據副本全都對外提供服務。有效提高系統性能。

在分佈式系統引入複製機制後,不同的數據節點之間由於網絡延時等原因很容易產生數據不一致和數據複製延遲(單獨一篇文章詳細說明覆制延遲的解決方案)的情況。複製機制的目的是為了保證數據的一致性。但是數據複製面臨的主要難題也是如何保證多個副本之間的數據一致性。

假設有這樣的場景,有兩個人同時去兩個不同的火車站買票(A去A火車站,B去B火車站),為了保證合理的賣票,需要在A火車站和B火車站之間共享關於剩餘票數的數據。但是A和B要買的票只剩下一張。一張票當然只能賣給一個人。 如果為了保證系統性能,那麼A和B在買票的時候應該都可以買票成功(因為他們在買票過程中餘票數據都顯示還有一張餘票)。兩人在買完票之後,系統在做數據複製時發現一張票被賣出了兩次,這時就要讓A和B兩人其中一人手中得票作廢掉。這時就要花費很大的力氣來通知後買到這張票的人這個消息。。。 如果為了保證數據一致性,那麼就需要在A買票的過程中,B只能等著。等A買票結束,並且把餘票結果同步到B火車站的售票窗口。然後B才能知道還有沒有餘票可以購買。

上面的例子可以簡單的說明一個系統如果想保證數據一致性很有可能影響其性能。因為併發的寫請求需要在前一個寫請求結束之後才能進行。

因此,如何能既保證數據一致性,又保證系統的性能,是每一個分佈式系統都需要重點考慮和權衡的。一致性模型可以在做這些權衡的時候給我們很多借鑑和思考。


分佈式系統的數據一致性


四、一致性模型

1、強一致性

當更新操作完成之後,任何多個後續進程或者線程的訪問都會返回最新的更新過的值。這種是對用戶最友好的,就是用戶上一次寫什麼,下一次就保證能讀到什麼。但是這種實現對性能影響較大。

2、弱一致性

系統並不保證續進程或者線程的訪問都會返回最新的更新過的值。系統在數據寫入成功之後,不承諾立即可以讀到最新寫入的值,也不會具體的承諾多久之後可以讀到。但會盡可能保證在某個時間級別(比如秒級別)之後,可以讓數據達到一致性狀態。

3、最終一致性

弱一致性的特定形式。系統保證在沒有後續更新的前提下,系統最終返回上一次更新操作的值。在沒有故障發生的前提下,不一致窗口的時間主要受通信延遲,系統負載和複製副本的個數影響。DNS是一個典型的最終一致性系統。

4、最終一致性模型的變種

  • 因果一致性:如果A進程在更新之後向B進程通知更新的完成,那麼B的訪問操作將會返回更新的值。如果沒有因果關係的C進程將會遵循最終一致性的規則。
  • 讀己所寫一致性:因果一致性的特定形式。一個進程總可以讀到自己更新的數據。
  • 會話一致性:讀己所寫一致性的特定形式。進程在訪問存儲系統同一個會話內,系統保證該進程讀己之所寫。
  • 單調讀一致性:如果一個進程已經讀取到一個特定值,那麼該進程不會讀取到該值以前的任何值。
  • 單調寫一致性:系統保證對同一個進程的寫操作串行化。


分佈式系統的數據一致性


上述最終一致性的不同方式可以進行組合,例如單調讀一致性和讀己之所寫一致性就可以組合實現。並且從實踐的角度來看,這兩者的組合,讀取自己更新的數據,和一旦讀取到最新的版本不會再讀取舊版本,對於此架構上的程序開發來說,會少很多額外的煩惱。

為了解決分佈式的一致性問題,在長期的研究探索過程中,湧現出了一大批經典的一致性協議和算法,其中比較著名的有二階段提交協議,三階段提交協議和Paxos算法。


分享到:


相關文章: