“每个本地 mutator 满足膨胀更新 $x\sqsubseteq m(x)$;”
形式陈述 ​
设
一串本地更新于是形成上升链
后发状态天然概括同一副本此前状态;反熵协议即使丢掉中间快照,只要最终送达某个支配它们的后继状态,早期更新仍被携带。另一种常见写法让 mutator 产生某个
膨胀函数与序单调函数不是同一条件。单调性要求
“更新向上”是内部状态约束,不等于用户可见值只增。PN-Counter 的内部正、负分量都只增,查询差值却可下降;OR-Set 删除元素时增加删除上下文,查询集合也会缩小。连续执行膨胀 mutators 仍形成上升链,因为每一步只需比较当时输入与输出;这不要求不同 API 之间具有交换性,本地程序顺序仍可影响 query。
直觉
状态消息可能乱序。若新状态总包含旧状态的信息,收到旧快照只会被 join 吸收,不会撤销新更新。膨胀性把“哪个快照较新”从物理时间问题改写成偏序包含问题:网络无需猜测发送顺序,只要合并即可。
删除和覆盖之所以需要元数据,是因为用户动作看似在做减法,而复制状态仍必须做加法。正确设计把“值不存在”表示为一种新增事实,例如“dot
膨胀性也不保证无限状态可回收。压缩若删除偏序所需证据,实际上会让状态向下跳;安全回收必须证明被删证据已由全局稳定条件永久替代。
例子与边界
Grow-only set 以
从
则从
膨胀但不单调的抽象例子可在菱形偏序
整数“赋值”
推论与应用
膨胀链允许反熵只传播较新的摘要,并让版本向量以逐分量最大值合并。Delta-state CRDT 进一步把一次膨胀分解成较小的半格元素,但接收端仍以 join 吸收,delta 不是必须恰一次执行的命令。
验证 mutator 时应先列出内部状态偏序,再逐个 API 证明更新后状态支配更新前状态。只检查 query 值会漏掉问题:两个内部状态可返回同一用户值,却携带不同因果证据,未来 merge 行为并不相同。批量更新也应证明等价于若干合法膨胀步骤或一次与某半格元素的 join。
参考资料
- Marc Shapiro et al., “Conflict-Free Replicated Data Types,” Stabilization, Safety, and Security of Distributed Systems, LNCS 6976, 2011, pp. 386–400.
- Marc Shapiro, Nuno Preguiça, Carlos Baquero, and Marek Zawirski, “A Comprehensive Study of Convergent and Commutative Replicated Data Types,” INRIA RR-7506, 2011, Sec. 3.1.
- Paulo Sérgio Almeida, “Approaches to Conflict-Free Replicated Data Types,” ACM Computing Surveys 56(3), Article 76, 2024, Sec. 3.