淺談協同文檔中的數據一致性

2020-01-03   sandag

在線文檔是一個數據一致性要求很強的項目,我們經常會提到一個在線文檔的技術:「協同衝突處理算法——OT」。這是協同編輯處理的核心。因為它保障了在多客戶端同時提交修改的情況下的數據一致性,用通俗一點的方式描述:多人在線編輯,每個人提交的內容不一樣,但通過協同衝突算法,最終都能看到一樣的內容。

但在這裡我們不想深入去探討協同編輯衝突算法的具體內容,對這塊有興趣的朋友可以參考之前我們團隊的博客,已經有過很多介紹。本文主要是介紹協同衝突算法產生的原因,以及它背後關於數據一致性的問題。

CAP 理論

CAP 理論是分布式算法裡面 非常非常重要的一個概念 ,幾乎所有的分布式系統都在應用這一理論。如果我們將在線文檔的客戶端看作是分布式系統中的節點,那麼協同編輯算法就是用於處理分布式系統中數據一致性問題。

CAP 理論這麼重要,那麼它究竟指的是什麼呢?C、A、P 每一個字母都代表了一個非常重要的概念

C Consistensy,一致性

A availability,可用性

P Partition Tolerance,分區容忍性

而 CAP 最重要的概念是 分布式系統中,CAP 三個條件中,最多只能同時滿足兩個

這是為什麼呢?而且光從概念上,很難去理解這句話。這裡我們挑一個例子來看:

假設在分布式系統中存在 100 個節點,但由於故障,使得網絡發生了分區,其中有一半的節點無法向另外一半節點通信,於是系統被分割為 A 區與 B 區。

那麼在網絡分區的情況下,客戶端發送請求嘗試來對 A 區一個節點進行數據寫入,由於 AB 區網絡不通,這時候無法同步寫入信息給到 B 區節點。

在這種場景下,究竟允不允許當前客戶端進行數據寫入呢?請思考一下。

1、如果允許客戶端數據寫入,那麼當前節點的 可用性 得到了保證,但是由於網絡分區,所以網絡不可觸達,數據無法同步。因此此時是無法滿足 一致性 ,也就是分布式系統中,同時訪問兩個節點,可能會返回不同數據。

2、如果不允許客戶端數據寫入,那麼當前節點的 一致性 得到了保證,所有節點數據都是一致的。但是由於數據都無法寫入,這時系統顯然是 「不可用」 的,也就是 可用性 無法滿足

這就是常見的 CP 與 AP 的組合。但為什麼沒有提到 CA 的組合呢?為什麼假設都是在允許網絡分區的情況下呢?答案是這裡的場景是分布式系統,如果不允許存在網絡分區,那麼顯然每次寫入數據都可以進行同步,自然一致性和可用性顯然得到了保障。但這也不是分布式系統了。

BASE 理論

但將這個理論放在協同場景下,好像又不適用了?假設在網絡差的情況下,兩個客戶端同時提交,雖然暫時一致性無法滿足,本地客戶端會看到不同的內容,但網絡恢復後,通過協同衝突算法數據也能保持一致,這不是既滿足了一致性又滿足了可用性嗎?

這個是對的,只是這裡的一致性不等於 CAP 理論的一致性,CAP 理論是假設在沒有網絡延遲的情況下的強一致性,也就是數據時刻都是一致的。而協同編輯的場景,我們需要了解另外的概念:BASE

既是無法做到強一致性(Strong consistency),但每個應用都可以根據自身的業務特點,採用適當的方式來使系統達到最終一致性(Eventual consistency)。

BA:Basically Avaliable(基本可用)

S: Soft State(軟狀態)

E: Eventually consistency(最終一致性)

BASE 的核心思想:在不滿足強一致性的情況下,也可以通過其他手段來達到最終一致性。

1、基本可用

允許損失部分可用性,允許犧牲響應時間、降級系統功能等操作

2、軟狀態

允許存在數據中間狀態,不要求強一致性,並不影響整體可用性,允許副本之間的數據同步延遲。

3、最終一致性

所有的副本,在最終都能達到數據一致的狀態,但不要求實時的強一致性。

最終一致性又會有許多劃分:讀寫一致性、寫讀一致性、單調讀一致性、單調寫一致性等。

在 BASE 理論中,我們可以看到協同編輯文檔的場景中,雖然 CAP 的強一致性無法滿足,但通過損失部分可用性,允許暫時的客戶端不一致情況,通過協同編輯衝突算法,可以解決數據不一致問題,達到了最終的數據一致性。

總結

通過協同編輯算法來解決數據衝突問題,其實屬於共識過程,而對於共識,有興趣的讀者可以進一步了解 Paxos、Raft、ZAB 等共識算法。了解 Paxos 是如何解決分布式系統中多節點的編號和數據同步問題、Raft 如何通過 Leader 選舉等操作來降低 Paxos 兩段 RPC 調用產生的延遲、Zookeeper 的 ZAB 算法又是如何解決分布式系統中的問題的。

最後,感謝大家等閱讀,分布式系統中的概念確實是屬於比較複雜而且解釋繁多的一部分,如有錯誤,歡迎斧正。