作為互聯網中的一員,我們時常沉浸在“分佈式”的氛圍當中——高可用、高可靠、高性能等等詞彙隨處可見,CAP、BASE、2PC、Paxos、Raft等等名詞也能信手捏來。不過,有些詞在我們“並不嚴謹”的傳播中逐漸被誤用了,或者說含糊不清了。今天,我們來簡單聊聊“Consistency”這個詞,即一致性。
Paxos、Raft等通常被誤稱為“一致性算法”。但是“一致性(Consistency)”和“共識(Consensus)”並不是同一個概念。Paxos、Raft等其實都是共識(Consensus)算法。
Leslie Lamport於1998年在ACM Transactions on Computer Systems上發表了一篇《The Part-Time Parliament》[1]的文章,這是Paxos算法第一次公開發表。但是發表之後,很多人還是覺得原來那篇太難理解了,之後Lamport又寫了一篇《Paxos Made Simple》[2],當我們想要學習一下Paxos的時候,可以直接看看這篇。
回到正題,我們在《Paxos Made Simple》中搜索“Consistency”一詞,如下圖所示,其實是毫無匹配結果的。
反觀,我們搜索“Consensus”一詞的時候,卻出現了很多匹配項。
也就是說,Paxos論文通篇提都沒提Consistency一詞,何來的“Paxos is a consistency algorithm”的說法。
與此類似的是,在Raft論文《In Search of an Understandable Consensus Algorithm (Extended Version)》[3]中開頭就對Raft給出了明確的定義:Raft is a consensus algorithm....,注意這裡是consensus,而不是consistency。
這時候我們不妨再打開字典。乍眼一看,字典中Consistency和Consenus譯意接近,都有“一致”的含義,但是仔細深究又有所不同:Consistency:一致性,Consensus:共識、一致的意見。
從專業的角度來講,我們通常所說的一致性(Consistency)在分佈式系統中指的是對於同一個數據的多個副本,其對外表現的數據一致性,如強一致性、順序一致性、最終一致性等,都是用來描述副本問題中的一致性的。而共識(Consensus)則不同,簡單來說,共識問題是要經過某種算法使多個節點達成相同狀態的一個過程。一致性強調結果,共識強調過程。
《分佈式系統概念與設計》一書中對共識問題進行了如下定義:為達到共識,每個進程 pi 最初處於未決(undecided)狀態,並且提議集合D中的一個值 vi 。進程之間互相通信,交換值。然後,每個進程設置一個決定變量(decision variable)di 的值。在這種情況下,它進入決定(decided)狀態。在此狀態下,他不再改變di。
下圖中給出了參與一個共識算法的3個進程。兩個進程提議“繼續”, 第三個進程提議“放棄”但隨後崩潰。保持正確的兩個進程都決定“繼續”。(其中i = 1, 2, ……, N; j = 1, 2, ……, N。)
共識算法的要求是在每次執行中滿足以下條件:
- 終止性:每個正確進程最終設置它的決定變量。
- 協定性:所有正確進程的決定值都相同,即如果 pi 和 pj 是正確的並且已進入決定狀態,那麼 di = dj。
- 完整性:如果正確的進程都提議同一個值,那麼處於決定狀態的任何正確進程已選擇了該值。
共識問題中所有的節點要最終達成共識,由於最終目標是所有節點都要達成一致,所以根本不存在一致性強弱之分。所以,以後我們看到“Paxos是一個強一致性算法”、“Raft是一個強一致性協議”等類似說法的時候,我們更要以一種“審視”的眼光去看待後面的內容。
在我們大多數人的大多數工作內容中,一致性(Consistency)與共識(Consensus)的差別其實無關痛癢。但是如果我們想抬高一個維度,深入的去研究一下分佈式領域的內容,那麼這些最基礎的概念如果區分不清楚的話,會對後面的學習過程產生很大的阻礙。
越是相近的詞彙,越要清楚的區分。就算是同一個單詞,也會有不同的含義解析,比如CAP和ACID中的C都是Consistency的縮寫,但這兩者在各自場景下的含義也並不相同。
- ACID的C指的是事務中的一致性,在一系列對數據修改的操作中,保證數據的正確性。即數據在事務期間的多個操作中,數據不會憑空的消失或增加,數據的每一個增刪改操作都是有因果關係的。比如用戶A向用戶B轉了200塊錢,不會出現用戶A扣了款,而用戶B沒有收到的情況。
- 在分佈式環境中,多服務之間的複製是異步,需要一定耗時,不會瞬間完成。在某個服務節點的數據修改之後,到同步到其它服務節點之間存在一定的時間間隔,如果在這個間隔內有併發讀請求過來,而這些請求又負載均衡到多個節點,可能會出現從多個節點數據不一致的情況,因為請求有可能會落到還沒完成數據同步的節點上。CAP中的C就是為了做到在分佈式環境中讀取的數據是一致的。
總的來說,ACID的C著重強調單數據庫事務操作時,要保證數據的完整和正確性,而CAP理論中的C強調的是對一個數據多個備份的讀寫一致性。
對於今天的知識點有什麼想說的嘛?不妨在留言區留下你的想法。
以上文章來源於朱小廝的博客 ,作者朱小廝
閱讀更多 妖精的雜七雜八 的文章