什么是一致性模型?
在分布式系統(tǒng)中,C(一致性) 和 A(可用性)始終存在矛盾。若想保證可用性,就必須通過復(fù)制、分片等方式冗余存儲。而一旦進行復(fù)制,又來帶多副本數(shù)據(jù)一致性的問題——一個副本的數(shù)據(jù)更新之后,其他副本必須要保持同步,否則數(shù)據(jù)不一致就可能導(dǎo)致業(yè)務(wù)出現(xiàn)問題。
因此,每次更新數(shù)據(jù)對所有副本進行修改的時間以及方式?jīng)Q定了復(fù)制代價的大小。全局同步與性能實際上是矛盾的,而為了提高性能,往往會采用放寬一致性要求的方法。因此,我們需要用一致性模型來理解和推理在分布式系統(tǒng)中數(shù)據(jù)復(fù)制需要考慮的問題和基本假設(shè)。
那么什么是一致性模型呢?
一致性模型本質(zhì)上是進程與數(shù)據(jù)存儲的約定:如果進程遵循某些規(guī)則,那么進程對數(shù)據(jù)的讀寫操作都是可預(yù)期的。
下圖即為 Jepsen 概括的常見的一致性模型:
不可用(Unavailable):粉色代表網(wǎng)絡(luò)分區(qū)后完全不可用。當出現(xiàn)網(wǎng)絡(luò)隔離等問題的時候,為了保證數(shù)據(jù)的一致性,不提供服務(wù)。熟悉 CAP 理論的同學(xué)應(yīng)該清楚,這就是典型的 CP 系統(tǒng)了。
- 嚴格可用 (Sticky Available):黃色代表嚴格可用。即使一些節(jié)點出現(xiàn)問題,在一些還沒出現(xiàn)故障的節(jié)點,仍然保證可用,但需要保證 client 的操作是一致的。
- 完全可用(Highly Available):藍色代表完全可用。就是網(wǎng)絡(luò)全掛掉,在沒有出現(xiàn)問題的節(jié)點上面,仍然可用。
一致性模型主要可以分為兩類:能夠保證所有進程對數(shù)據(jù)的讀寫順序都保持一致的一致性模型稱為強一致性模型,而不能保證的一致性模型稱為弱一致性模型。
強一致性模型
強一致性包含線性一致性和順序一致性,其中前者對安全性的約束更強,也是分布式系統(tǒng)中能保證的最好的一致性。
線性一致性(Linearizable Consistency)
線性一致性是最嚴格的且可實現(xiàn)的單對象單操作一致性模型。在這種模型下,寫入的值在調(diào)用和完成之間的某個時間點可以被其他節(jié)點讀取出來。且所有節(jié)點讀到數(shù)據(jù)都是原子的,即不會讀到數(shù)據(jù)轉(zhuǎn)換的過程和中間未完成的狀態(tài)。
要想達到線性一致,需要滿足以下條件:
- 任何一次讀都能讀取到某個數(shù)據(jù)最近的一次寫的數(shù)據(jù)。
- 所有進程看到的操作順序都跟全局時鐘下的順序一致。
- 所有進程都按照全局時鐘的時間戳來區(qū)分事件的先后,那么必然所有進程看到的數(shù)據(jù)讀寫操作順序一定是一樣的
我們發(fā)現(xiàn),這個要求十分苛刻,難以在現(xiàn)實中實現(xiàn)。因為各種物理限制使分布式數(shù)據(jù)不可能一瞬間去同步這種變化。(通信是必然有延遲的,一旦有延遲,時鐘的同步就沒法做到一致。)
順序一致性(Sequential Consistency)
由于線性一致的代價高昂,因此人們想到,既然全局時鐘導(dǎo)致嚴格一致性很難實現(xiàn),那么我們能否放棄了全局時鐘的約束,改為分布式邏輯時鐘實現(xiàn)呢?
Lamport 在 1979 年就提出的順序一致性正是基于上述原理。順序一致性中所有的進程以相同的順序看到所有的修改。讀操作未必能及時得到此前其他進程對同一數(shù)據(jù)的寫更新,但是每個進程讀到的該數(shù)據(jù)的不同值的順序是一致的。
其需要滿足以下條件:
- 任何一次讀寫操作都是按照某種特定的順序。
- 所有進程看到的讀寫操作順序都保持一致。
我們發(fā)現(xiàn)他們都能夠保證所有進程對數(shù)據(jù)的讀寫順序保持一致。那么它與線性一致性有什么不同呢?
盡管順序一致性通過邏輯時鐘保證所有進程保持一致的讀寫操作順序,但這些讀寫操作的順序跟實際上發(fā)生的順序并不一定一致。而線性一致性是嚴格保證跟實際發(fā)生的順序一致的。
我們以下圖為例:
例子1:線性一致性與順序一致性的區(qū)別
圖 a 滿足了順序一致性,但未滿足線性一致性。 從全局時鐘來看,p2 的 read(x,0) 在 p1 的 write(x,4) 之后,但是 p1 卻讀出了舊的數(shù)據(jù)。因此不滿足線性一致性。但是兩個進程各自的讀寫順序卻是合理的,進程之間也沒有產(chǎn)生沖突,因此從這兩個進程的視角來看,執(zhí)行流程是這樣的 write(y,2)、read(x,0)、 write(x,4)、read(y,2)。此時滿足順序一致性。
- 圖 b 滿足線性一致性。 因為每個讀操作都讀到了該變量的最新寫的結(jié)果,同時兩個進程看到的操作順序與全局時鐘的順序一樣。
- 圖 c 不滿足順序一致性。 因為從進程 P1 的角度看,它對變量 y 的讀操作返回了結(jié)果 0。那么就是說,P1 進程的對變量 y 的讀操作在 P2 進程對變量 y 的寫操作之前,x 變量也如此。此時兩個進程存在沖突,因此這個順序不滿足順序一致性。
弱一致性模型
弱一致性是指系統(tǒng)在數(shù)據(jù)成功寫入之后,不承諾立即可以讀到最新寫入的值,也不會具體承諾多久讀到,但是會盡可能保證在某個時間級別之后,可以讓數(shù)據(jù)達到一致性狀態(tài)。其中包含因果一致性和最終一致性、客戶端一致性。
因果一致性(Causal Consistency)
什么是因果關(guān)系呢?
如果事件 B 是由事件 A 引起的或者受事件 A 的影響,那么這兩個事件就具有因果關(guān)系。
因果一致性是一種弱化的順序一致性模型,它僅要求有因果關(guān)系的操作順序是一致的,沒有因果關(guān)系的操作順序是隨機的。
因果一致性的條件包括:
- 所有進程必須以相同的順序看到具有因果關(guān)系的讀寫操作。
- 不同進程可以以不同的順序看到并發(fā)的讀寫操作。
我們?nèi)绾未_定是否具有因果關(guān)系呢?如何傳播這些因果關(guān)系呢?
即通過邏輯時鐘來保證兩個寫入是有因果關(guān)系的。而實現(xiàn)這個邏輯時鐘的一種主要方式就是向量時鐘。向量時鐘算法利用了向量這種數(shù)據(jù)結(jié)構(gòu),將全局各個進程的邏輯時間戳廣播給所有進程,每個進程發(fā)送事件時都會將當前進程已知的所有進程時間寫入到一個向量中,而后進行傳播。
最終一致性(Eventual Consistency)
最終一致性是更加弱化的一致性模型,它被表述為副本之間的數(shù)據(jù)復(fù)制完全是異步的,如果數(shù)據(jù)停止修改,那么副本之間最終會完全一致。而這個最終可能是數(shù)毫秒到數(shù)天,乃至數(shù)月,甚至是“永遠”。
對于最終一致性,我們主要關(guān)注以下兩點:
- **最終是多久。**通常來說,實際運行的系統(tǒng)需要能夠保證提供一個有下限的時間范圍。
- **并發(fā)沖突如何解決。**一段時間內(nèi)可能數(shù)據(jù)可能多次更新,到底以哪個數(shù)據(jù)為準?通常采用最后寫入成功或向量時鐘等策略。
因為在數(shù)據(jù)寫入與讀取完全不考慮別的約束條件,因此最終一致性具有最高的并發(fā)度,經(jīng)常被應(yīng)用于對性能要求高的場景中。
客戶端一致性(Client-centric Consistency)
在最終一致性的模型中,如果客戶端在數(shù)據(jù)不同步的時間窗口內(nèi)訪問不同的副本的同一個數(shù)據(jù),會出現(xiàn)讀取同一個數(shù)據(jù)卻得到不同的值的情況。為了解決這個問題,有人提出了以客戶端為中心的一致性模型。
客戶端一致性是站在一個客戶端的角度來觀察系統(tǒng)的一致性。其保證該客戶端對數(shù)據(jù)存儲的訪問的一致性,但是它不為不同客戶端的并發(fā)訪問提供任何一致性保證。
分布式數(shù)據(jù)庫中,一個節(jié)點很可能同時連接到多個副本中,復(fù)制的延遲性會造成它從不同副本讀取數(shù)據(jù)是不一致的。而客戶端一致性就是為了定義并解決這個問題而存在的,這其中包含了寫跟隨讀、管道隨機訪問存儲兩大類別。
寫跟隨讀(Writes-Follow-Reads Consistency)
寫跟隨讀的另一個名字是回話因果(session causal)??梢钥吹剿c因果一致的區(qū)別是,它只針對一個客戶端。 即對于一個客戶端,如果一次讀取到了寫入的值 V1,那么這次讀取之后寫入了 V2。從其他節(jié)點看,寫入順序一定是 V1、V2。
管道隨機訪問存儲(PRAM,Pipeline Random Access Memory)
管道隨機訪問存儲的名字來源于共享內(nèi)存訪問模型。其對于單個進程的寫操作都被觀察到是順序的,但不同的進程寫會觀察到不同的順序。
其可拆解為以下三種一致性:
- 單調(diào)讀一致性(Monotonic-read Consistency):它強調(diào)一個值被讀取出來,那么后續(xù)任何讀取都會讀到該值,或該值之后的值,而不會讀取到舊值。
- 單調(diào)寫一致性(Monotonic-write Consistency):如果從一個節(jié)點寫入兩個值,它們的執(zhí)行順序是 V1、V2。那么從任何節(jié)點觀察它們的執(zhí)行順序都應(yīng)該是 V1、V2。
- 讀你所寫一致性(Read-your-writes Consistency):一個節(jié)點寫入數(shù)據(jù)后,在該節(jié)點或其他節(jié)點上是一定能讀取到這個數(shù)據(jù)的。
能夠同時滿足以上三種一致性的即為滿足 PRAM。
PRAM、因果一致、線性一致到底有什么區(qū)別呢?
例子2:因果一致、順序一致、PRAM 的區(qū)別
圖 a 滿足了順序一致性與因果一致性。 圖上的進程都滿足相同的順序與因果關(guān)系,因此滿足順序一致性與因果一致性。
- 圖 b 滿足了因果一致性,但未滿足順序一致性。 對于進程 p3 和 p4 其看到的 p1 和 p2 的執(zhí)行順序不一致,因此不滿足順序一致性。但是由于 p1 與 p2 的寫入沒有任何因果關(guān)系,所以此時滿足因果一致性。
- 圖 c 滿足了 PRAM,但未滿足因果一致性。 由于 p2 的 r(x,4) 依賴于 p1 的 w(x,4),此時兩者存在因果關(guān)系。然而對于進程 p3 和 p4 而言,其看到的 p1 和 p2 執(zhí)行順序不同,因此此時并不滿足因果一致性。但此時我們再來分析它們的觀察順序,此時 p4 觀察的到順序是 w(x.7)、w(x,2)、w(x,4)。而 p3 觀察到的是 w(x,2)、w(x,4)、w(x,7)。盡管此時它們對不同進程寫操作觀察的順序不同,但是對于同一個進程的寫操作觀察順序是一致的,因此其滿足 PRAM 一致性。
下圖即為上面討論的幾種一致性模型的關(guān)系:
一致性模型之間的關(guān)系
事務(wù)隔離性
在一開始那張一致性模型圖中,其實是有兩個分支的,一個對應(yīng)的就是數(shù)據(jù)庫里面的隔離性(Isolation),另一個其實對應(yīng)的是分布式系統(tǒng)的一致性(Consistency)。
事務(wù)隔離是描述并行事務(wù)之間的行為,而一致性是描述非并行事務(wù)之間的行為。其實廣義的事務(wù)隔離應(yīng)該是經(jīng)典隔離理論與一致性模型的一種混合。
潛在問題
如下即數(shù)據(jù)庫實現(xiàn)中遇到的各種各樣的 isolation 問題。
- P0 Dirty Write(臟寫):一個事務(wù)修改了另一個尚未提交的事務(wù)已經(jīng)修改的值。
- P1 Dirty Read(臟讀):一個事務(wù)讀取到了另一個執(zhí)行到一半的事務(wù)中修改的值。
- P2 Non-Repeatable Read(不可重復(fù)讀):一個事務(wù)讀取過程中讀到了另一個事務(wù)更新后的結(jié)果。
- P3 Phantom(幻讀):某一事務(wù) A 先挑選出了符合一定條件的數(shù)據(jù),之后另一個事務(wù) B 修改了符合該條件的數(shù)據(jù),此時 A 再進行的操作都是基于舊的數(shù)據(jù),從而產(chǎn)生不一致。
- P4 Lost Update(丟失更新):更新被另一個事務(wù)覆蓋。
- P4C Cursor Lost Update(游標丟失更新):與 Lost Update 類似,只是發(fā)生于 cursor 的操作過程之中。
- A5A Read Skew(讀傾斜):由于事務(wù)的交叉導(dǎo)致讀取到了不一致的數(shù)據(jù)。
- A5B Write Skew(寫傾斜):兩個事務(wù)同時讀取到了一致的數(shù)據(jù),然后分別進行了滿足條件的修改,但最終結(jié)果破壞了一致性。
隔離級別
對于分布式數(shù)據(jù)庫來說,原始的隔離級別并沒有舍棄,而是引入了一致性模型后,擴寬數(shù)據(jù)庫隔離級別的內(nèi)涵。其中共有如下數(shù)種隔離級別:
- Read Uncommitted(讀未提交):事務(wù)執(zhí)行過程中能夠讀到未提交的修改。
- Read Committed(讀已提交):事務(wù)執(zhí)行過程中能夠讀到已提交的修改。
- Monotonic Atomic View(單調(diào)原子視圖):在 Read Committed 的基礎(chǔ)上加上了原子性的約束,觀測到其他事務(wù)的修改時會觀察到完整的修改。
- Cursor Stability(穩(wěn)定游標):使用 cursor 讀取某個數(shù)據(jù)時,這個不能被其他事務(wù)修改直至 cursor 釋放或事務(wù)結(jié)束。
- Snapshot Isolation(快照隔離級別):即使其他事務(wù)修改了數(shù)據(jù),重復(fù)讀取都會讀到一樣的數(shù)據(jù)。
- Repeatable Read(可重復(fù)讀):每個事務(wù)在獨立、一致的 snapshot 上進行操作,直至提交后其他事務(wù)才可見。
- Serializable(串行化):事務(wù)按照一定的次序順序執(zhí)行。
對應(yīng)的可能發(fā)生的問題如下
P(Possible):會發(fā)生。
- SP(Sometimes Possible):有時候可能發(fā)生。
- NP(Not Possible):不可能發(fā)生。
-
數(shù)據(jù)存儲
+關(guān)注
關(guān)注
5文章
999瀏覽量
51737 -
模型
+關(guān)注
關(guān)注
1文章
3520瀏覽量
50420 -
分布式系統(tǒng)
+關(guān)注
關(guān)注
0文章
147瀏覽量
19632
發(fā)布評論請先 登錄
一致性測試系統(tǒng)的技術(shù)原理和也應(yīng)用場景
一行代碼,保障分布式事務(wù)一致性—GTS:微服務(wù)架構(gòu)下分布式事務(wù)解決方案
順序一致性和TSO一致性分別是什么?SC和TSO到底哪個好?
藍鯨集群文件系統(tǒng)中資源交互一致性協(xié)議
分布式一致性算法Yac

基于消息通信的分布式系統(tǒng)最終一致性平臺

DSA系統(tǒng)的全局一致性需求分析

分布式大數(shù)據(jù)不一致性檢測
一致性哈希是什么?為什么它是可擴展的分布式系統(tǒng)架構(gòu)的一個必要工具
分布式系統(tǒng)的CAP和數(shù)據(jù)一致性模型
基于自觸發(fā)一致性算法的分布式分層控制策略

一種更安全的分布式一致性算法選舉機制

評論