1. 程式人生 > >分布式系統的一致性探討

分布式系統的一致性探討

數據庫 分布式系統 模型 發現 經典的 火車 人在 寫入 難題

http://blog.jobbole.com/95618/

隨著大型網站的各種高並發訪問、海量數據處理等場景越來越多,如何實現網站的高可用、易伸縮、可擴展、安全等目標就顯得越來越重要。為了解決這樣一系列問題,大型網站的架構也在不斷發展。提高大型網站的高可用架構,不得不提的就是分布式。在《初識分布式系統》一文中簡單介紹了分布式的基本概念,本文將在上篇文章的基礎上繼續學習分布式的一致性問題。主要介紹分布式一致性的基本概念、重要性、一致性模型等。

一致性的重要性

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

這裏先簡單提一下,由於一個分布式系統不可能放棄一致性,那麽為什麽有的架構師還說在某些場景中可以犧牲一致性呢?通常這裏說的放棄一致性指的是放棄數據的強一致性(後文介紹什麽是強一致性)。

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

數據一致性

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

為什麽會有數據一致性問題

在初識分布式系統中我們介紹過,雖然分布式系統有著諸多優點,但是由於采用多機器進行分布式部署的方式提供服務,必然存在著數據的復制。分布式系統的數據復制需求主要來源於以下兩個原因:

可用性。將數據復制到分布式部署的多臺機器中,可以消除單點故障,防止系統由於某臺(些)機器宕機導致的不可用。 性能。通過負載均衡技術,能夠讓分布在不同地方的數據副本全都對外提供服務。有效提高系統性能。

在分布式系統引入復制機制後,不同的數據節點之間由於網絡延時等原因很容易產生數據不一致的情況。復制機制的目的是為了保證數據的一致性。但是數據復制面臨的主要難題也是如何保證多個副本之間的數據一致性。


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

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

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

一致性模型

強一致性

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

弱一致性

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

最終一致性

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

最終一致性模型的變種

因果一致性:如果A進程在更新之後向B進程通知更新的完成,那麽B的訪問操作將會返回更新的值。如果沒有因果關系的C進程將會遵循最終一致性的規則。

讀己所寫一致性:因果一致性的特定形式。一個進程總可以讀到自己更新的數據。

會話一致性:讀己所寫一致性的特定形式。進程在訪問存儲系統同一個會話內,系統保證該進程讀己之所寫。

單調讀一致性:如果一個進程已經讀取到一個特定值,那麽該進程不會讀取到該值以前的任何值。

單調寫一致性:系統保證對同一個進程的寫操作串行化。

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


為了解決分布式的一致性問題,在長期的研究探索過程中,湧現出了一大批經典的一致性協議和算法,其中比較著名的有二階段提交協議,三階段提交協議和Paxos算法。 下一篇文章將介紹這些和分布式一致性相關的協議和算法。

分布式系統的一致性探討