《Conflict free replicated data types》 阅读笔记。


论文地址

1. 最终一致性

1.1. Eventual Consistency

一个分布式系统是最终一致的,需满足以下条件:

  • Eventual delivery: 在健康节点上执行的更新操作最终会被传递至所有健康节点,也就是说 fcifcj,i,j[1,,n]fcifcj,i,j[1,,n],其中 cici 是节点 pipi 的 causal history
  • Convergence: causal history 相同的健康节点最终会收敛至相同的状态,也就是说 ci=cjsisj,i,j[1,,n]ci=cjsisj,i,j[1,,n]
  • Termination: 所有操作会终止

在上述说明中, 表示 eventually 表示 always,详见 Temporal logic。至于 causal history,可以理解为该节点已执行操作的集合。

1.2. Strong Eventual Consistency

一个分布式系统是强最终一致的,需在满足最终一致的条件下,额外满足以下约束:

  • Strong Convergence: 执行相同操作集合的健康节点具有相同的状态,也就是说 ci=cjsisj,i,j[1,,n]ci=cjsisj,i,j[1,,n]

PS: 最终一致性只包含 liveness guarantee,而强最终一致对系统的中间状态进行了约束 (safety guarantee)

2. 系统模型

2.1. 符号说明

符号 含义
pipi process ii
sisi process pipi has state siSsiS, called its payload
s0s0 初始状态
qq query
tt prepare-update
uu update
mm merge
PP communication protocol
fki(a)fki(a) 在节点 pipi 上执行的 kthkth 操作, ffqq, uumm, aa 是参数
Ki(f)Ki(f) 在节点 pipi 上操作 ff 执行的序数

2.2. State-based Convergent Replicated Data Type(CvRDT)

Causal History

我们定义一个对象的 causal hisatory(stated-based)C=[c1,,cn]C=[c1,,cn],其中 cici 经历了一系列中间态 c0i,,cki,c0i,,cki,。初始时,c0i=,i[1,,n]c0i=,i[1,,n],在节点 pipi 上执行的 kthkth 操作分为以下三种情况:

cki={ck1i,f=qck1i{uki(a)},f=uki(a)ck1icki,f=mki(ski)cki=⎪ ⎪⎪ ⎪ck1i,f=qck1i{uki(a)},f=uki(a)ck1icki,f=mki(ski)

Monotonic semilattice object

我们用 (S,,s0,q,u,m) 表示基于状态的对象,其中 表示 partial order。若其满足以下约束,我们称其为 monotonic semilattice object:

  1. Poset (S,) 构成一个 Join-semilattice
  2. Merge 操作满足: sm(s)=ss
  3. 在更新操作下状态 s 满足单调性,即 ssu

回顾之前的知识,可以知道第 1 条约束的意思是集合 S 中任意非空子集都有 join,第 2 条约束说明 merge 即为 join

CvRDT

Assuming eventual delivery and termination, any state-based object that satisfies the monotonic semilattice property is SEC.

CvRDT 使用 (S,,s0,q,u,m) 表示。

从上可以看出,在 CvRDT 中, 需要满足以下条件:

  • 状态满足单调性,消息最终可达
  • 状态更改操作为 Merge 需满足交换律,结合律,幂等

2.3. Op-based Commutative Replicated Data Type(CmRDT)

Causal History

我们定义一个对象的 causal hisatory(op-based)C=[c1,,cn],其中 ci 经历了一系列中间态 c0i,,cki,。初始时,c0i=,i[1,,n],在节点 pi 上执行的 kth 操作分为以下两种情况:

cki={ck1i,f=q,tck1i{uki(a)},f=uki(a)

Happened-before

Update (t,u) happended-before (t,u) iff the former is delivered when the latter executes: (t,u)(t,u)uck1j, where t executeds at pj and k=Kj(t).

Commutativity

Updates (t,u) and (t,u) commute, iff for any reachable replica state s where both u and u are enabled, u (resp. u) remains enabled in state su(resp. su), and suusuu.

CmRDT

Assuming causal delivery of updates and method termination, any op-based object that satisfies the commutativity property for all concurrent updates, and whose delivery precondition is satisfied by causal delivery, is SEC.

CmRDT 使用 (S,s0,q,t,u,P) 表示。

从上可以看出,在 CmRDT 中, 需要满足以下条件:

  • Update 操作要么可确定明确的因果顺序,要么满足可交换
  • 消息传输提供 exactly once 的保证

3. 一些结论

  • CvRDTs and CmRDTs are equivalent
  • SEC is incomparable to sequential consistency

4. CRDT 示例

4.1. Counters

我们使用 CvRDT 的框架来构造一个分布式计数器 (S,n,s0,value,inc,maxn):

符号 含义
S 状态集合,其中 s=v=[v1,,vn] 表示计数器的状态
n vnvvivi,i[1,,n]
s0 [0,,0]
value value(v)=ivi
inc 在节点 piinc(v)=v,其中 $v'i = v_i + 1 \cdot \mathbb{I}{\{j\}}(i), \forall i \in [1, \dots, n]$
maxn smaxn(s)=[max(v1,v1),,max(vn,vn)]

可以发现上述定义的是一个只增计数器,如果想可增可减的话,可以使用两个只增计数器构成。

4.2. Set

一个 add-only 的集合可以构造为 (S,,,value,add(e),),其中 sadd(e)=s{e},很明显这也是一个 CRDT。

A comprehensive study of Convergent and Commutative Replicated Data Types 中作者定义了可增可减的两种 Set,但是也有较强的 assumption…

  • 2P-Set:维护两个集合:add-only 和 remove-only。只能适用于集合中的元素只会被 add/remove 一次的情况
  • U-Set: 维护一个支持 add/remove 的集合。需要满足两个条件:
    • remove 过的元素不会再 add
    • add 操作确保在 remove 前