關於分散式概念的一些個人理解
起因
最近想了解分散式相關的概念,剛好之前也對像是線性一致性,順序一致性,因果一致性,序列化,也就是CAP和ACID各種概念非常混亂和不解,有幸看到一些文章,有了一些新的認知,特此記錄。
正文
CAP和ACID的研究物件不一樣
首先,CAP和ACID二者討論範圍並不一樣,
http://www.bailis.org/blog/linearizability-versus-serializability/
One of the reasons these definitions are so confusing is that linearizability hails from the distributed systems and concurrent programming communities, and serializability comes from the database community. Today, almost everyone uses both
distributed systems and databases, which often leads to overloaded terminology (e.g., “consistency,” “atomicity”).
這篇文章裡面很明確的說了就是CAP這個概念是從併發社群出來,然後ACID這個概念是資料庫相關社群,最後由於技術發展,二者交融,產生了概念的過載(“overload”)。
CAP和ACID中的“一致性”
然後就是CAP裡面的C究竟是什麼了,還是參考的上面的文章,這個一致性主要是討論的單個操作,單個物件,時間順序之間的表現形式(single-operation, single-object, real-time order),也就是對不同分散式系統中這三項之間對外如何表現按照“一致性程度”進行建模,也就有了線性一致性(Linearizable),順序一致性(Sequential),因果一致性(Casual)等等一致性模型,描述的是系統中讀寫物件的和標準時鍾之間(每個一致性模型都會假設存在的一個標準的精確時鐘【普通系統會有時鐘漂移問題】)的可能情況。這篇文章裡面有些簡單的一致性模型介紹,感興趣可以看看哦 https://www.cs.columbia.edu/~du/ds/assets/lectures/lecture12.pdf
接下來是ACID了,其實這個是資料庫事務的概念,而事務研究的物件是多個操作,多個物件,以及這一系列操作加之物件之後對外呈現出的操作順序性問題(multi-operation, multi-object, arbitrary total order)【注意:事務研究的時候是不怎麼強調時間概念的】,如果是你去想這個問題的話,你肯定會好奇這麼多操作之間怎麼互動吧,我怎麼描述這麼多操作作為一個整體(A,原子性)相互交叉執行,也就是事務併發的時候的一些表現(I,也就是隔離性),於是按照嚴重程度進行了一定的分級,也就有了各種隔離級別,描述事務併發時候的讀寫表現,和上面的一致性模型一樣,都是抽象出來方便研究的。補充一句,這裡ACID的C更多的是一種對於事務的“期望”,就是我希望設計好的資料庫能夠滿足一致性(滿足資料庫約束,業務執行過程中的一些不變數[比如金額總數不變])。
CAP和ACID有關係嗎?
那ACID的I和CAP中的C到底有關係嗎?畢竟二者研究物件都不太一樣。還真有,看下面這張圖
https://xzhu0027.gitbook.io/blog/misc/index/consistency-models-in-distributed-system#session-guarantees
CAP的C和ACID裡面的I在嚴格一致性(Strict Serializability)產生交集,這也是分散式系統最強的一致性模型,這裡有個有趣的說法,就是嚴格一致性就是序列化加上了真實時間約束,然後當嚴格一致性中的事務操作只包含一個原子操作的時候就等同於線性一致性,有趣吧。
題外話:從上面圖的標記也可以看出來,CAP理論中的CA不能夠共存其實是指線性一致性和順序一致性不能和可用性共存,因為如果對於MongoDB瞭解過的話,Mongo其實提供了Casual Consitency Session這樣子一個一致性模型(個人感覺更像是這個圖裡面的PRAM級別)
Quorum機制、共識演算法與CAP
- Quorum機制從維基百科看就是其實一種抽屜原理的應用,核心就是少數服從多數,在客戶端訪問服務進行讀寫請求(Mongo的read/write concern)、其他共識演算法選主過程等諸多方面都有應用。單獨靠Quorum是沒有辦法很好解決併發衝突(就是多個修改請求同時進行)以及對外表現的一致性的( https://zhuanlan.zhihu.com/p/73371271 )。比如raft就是Quorum + 版本號管理實現的強一致性
- 共識演算法就是常說的paxos,raft,gossip,這些演算法是為了保證CAP中的C(各節點資料的一致性)的手段,是系統內部達成一致、進行資料同步的一系列演算法,根據對外表現上,有強一致性的演算法:raft,以及弱一致性的演算法:gossip。注意這裡的一致性是指系統內部各節點在同步過程中的不一致狀態是否會被外界觀察到
http://icyfenix.cn/distribution/consensus/gossip.html
Paxos、Raft、ZAB 等分散式演算法經常會被稱作是“強一致性”的分散式共識協議,其實這樣的描述摳細節概念的話是很彆扭的,會有語病嫌疑,但我們都明白它的意思其實是在說“儘管系統內部節點可以存在不一致的狀態,但從系統外部看來,不一致的情況並不會被觀察到,所以整體上看系統是強一致性的”。與它們相對的,還有另一類被冠以“最終一致性”的分散式共識協議,這表明系統中不一致的狀態有可能會在一定時間內被外部直接觀察到。一種典型且極為常見的最終一致的分散式系統就是DNS 系統,在各節點快取的 TTL 到期之前,都有可能與真實的域名翻譯結果存在不一致。在本節中,筆者將介紹在比特幣網路和許多重要分散式框架中都有應用的另一種具有代表性的“最終一致性”的分散式共識協議:Gossip 協議
分散式事務、外部一致性
分散式事務簡單理解下就是多個節點間的事務,也有相應的ACID的說法,這裡一致性就有外部一致性、內部一致性這種說法。
參考:https://blog.csdn.net/qq_41775852/article/details/115379491
https://www.zhihu.com/question/56073588
這一塊由於不太深入瞭解過,所以不敢嘗試下任何斷言。換個思路嘗試從一個實現者的角度,結合現有Mysql的實現去理解這個問題。
首先我們都知道事務是資料庫討論的一項技術,那麼分散式事務其實對應的就是分散式資料庫。
那麼你會怎麼去實現分散式資料庫呢?
1. “縫合怪”,利用中介軟體(比如ShardingJDBC)整合各種現有的資料庫
2. “原生”,比如Oceanbase,大致思路就是 複製狀態機+2PC,也就是各分片間的一致性由共識演算法保證,分片間的事務提交用二階段提交來實現
http://files.catwell.info/misc/mirror/2014-ongaro-raft-phd.pdf
資料庫有了,事務提交也實現了,別忘了,事務是多個操作,多個物件,如果多個事務併發了,我怎麼保證併發呢,也就是 I 隔離性?
一個常規的思路是基於鎖去保護資源,簡單粗暴。效率肯定不高。於是類比Mysql的MVCC實現,是否可以在分散式資料庫裡面實現快照呢?我們知道Mysql的快照是基於事務id的單調遞增特性的,可是分散式的節點他們的事務id可不一定是單調的,為了找到這樣一種單調遞增特性的東西,很自然就想到了時間戳,到這裡出現時間的概念,是不是和CAP的一致性模型開始關聯上了?所以,從這層來講我還是具體更傾向於 外部一致性 = 嚴格一致性(Strict Serializability)這種講法的。
題外話:貌似就是這種快照實現,以及單機時鐘不準確,牽扯出了一大堆原生分散式資料庫的問題,比如什麼邏輯時鐘,True Time之類的
小結
其實我們在閱讀分散式相關的問題時候,腦海中要有個簡單的分散式的問題模型,就是多節點,多資料副本,多操作,最關鍵的是操作還要儘可能併發(併發意味著衝突,延伸出來需要鎖,MVCC的概念)。然後每個理論、模型其實就是研究了這個問題的某個方面,嘗試去說明一些東西或者特徵。
希望和我有同樣困惑的朋友看完這篇文章之後有所收穫。
參考連結
在上面都粘了的,這裡就不寫了。
https://jepsen.io/consistency
https://www.mongodb.com/docs/manual/reference/read-concern-majority/