各種「一致性」
來自專欄基礎架構
Consistency,一致性這個詞經常見到,並且還是在不同的場景下有些不同的含義,在這把我見到的一些總結一下。
一致性模型
一致性並不是一種性質,更合理的應該看做是一組不同要求的模型,也就是常說的一致性模型。一個模型給定一組規則規定相關的操作導致的狀態轉化,如果一個系統的操作歷史在任何情況下都符合這個規則,那我們認為這個系統是符合這個一致性模型的。
為了滿足不同性能以及一致性的需求,人們提出了多種一致性模型,從強到弱(就是對於並發讀寫順序規定的嚴格性)分別有linearizability, sequential consistency, causal consistency 和 PRAM等等,同時後者的性能也依次比前者高。
這些不同的一致性模型大都是在研究多核CPU並發時對於內存的訪問時提出的,當然也適用於分散式系統。在分散式存儲中所提到的滿足一致性一般指副本數據滿足線性一致性(linearizability),不過說不滿足一致性的一般都會滿足最終一致性,否則副本就沒啥意義了。
一致性(共識)演算法
一致性演算法就是人們常提到的Paxos、Multi-Paxos、Raft等等,實際上這些演算法應該稱為共識(consensus)演算法,就是多個節點對某一提案達成共識的演算法,並且在論文中也是只有consensus,並沒有提到consistency。只是因為通常使用這些共識演算法來實現容錯複製狀態機,維持不同副本間日誌的一致,所以習慣稱之為一致性演算法。
副本一致性
在分散式存儲系統中都會維持多分副本來提高數據可靠性,這就帶來了副本間數據的一致性問題,通常所說的一致性大都是指在這裡的一致性問題。
在研究這個問題常用的網路模型和故障模型下,副本間的網路數據可能會無限延遲、重複到達,而副本節點也可能發生重啟或故障。一個系統的一致性問題一般表現為客戶端訪問多個副本數據的一致性問題。
先看什麼是副本的一致性,一般說一個系統是強一致的就是說客戶端訪問數據表現為線性一致,就是寫入了一個值之後肯定能讀出來,讀取一個值之後再讀這個值如果中間沒有修改過兩次讀的值一定相同。
再看如何實現,比較容易想到的做法就是寫和讀時都訪問所有副本,但這樣帶來的問題就是延遲太大,故障恢復太慢太複雜。再者就是單master讀寫,由master向slave複製數據,這樣正常情況下是能保持線性一致的。但是一旦master死掉,那就需要選一個新的與master數據一致的slave來負責,而且這裡為了保證不出現多個master,需要另一個一致性系統來選。還有方法就是直接在副本間使用共識演算法來保證數據一致。所以在這裡如何保持副本間的一致性就轉化為了使用共識演算法的問題。
前面說的master向slave同步,如果是非同步複製,在master發生故障選擇新的slave提升為master時很有可能新的master缺少部分數據,從而損失了一致性,所以在這裡需要權衡性能和數據可靠性需求,選擇不同的同步複製slave個數來實現不同的可靠性。
所以對於副本一致性的解決,要麼採用共識演算法,要麼採用master-slave方式,同時需要master-slave間同步複製以及需要一個共識系統選master。
最終一致性
最終一致性也是講的是副本間數據同步的最終一致,在"一段時間"內所有副本達到一致狀態,但是一段時間並沒有規定多久,當然也很有可能是"永遠"。最終一致是個比較模糊的概念,當單master的系統正常工作時,對外表現的是線性一致,但在master崩潰且一個並沒有與master數據一致的slave被選為了新master,那這時系統該不該說是最終一致的呢。
CAP
這裡的一致性指的也應該是副本數據對於客戶端的線性一致性表現。在發生網路或節點故障恢復後系統對於用戶表現的數據是否線性一致。
ACID
這裡的consistency是在事務中的概念,這裡更多的是應用方面的概念,不是由資料庫層面來保證的。應用應該利用資料庫的Atomic及Isolation性質來保證自己數據的一致性。
參考
1. Strong consistency models
2. 《Designing Data-Intensive Applications》
3. 分散式系統一致性的發展歷史 (一)
4. 分散式系統一致性的發展歷史 (二)
推薦閱讀:
※大國崛起:資料庫領域的中國力量
※PhxPaxos架構設計、實現分析
※UCloud雲資料庫團隊誠招分散式資料庫研發
※【技術解密】SequoiaDB分散式存儲原理
※TiDB 分散式資料庫在轉轉公司的應用實踐