我在这里找到了一篇关于 delta 状态 CRDT 的很好的介绍性文章。
他们的方法使用带有根版本向量的映射,并用“点”列表标记每个key。版本向量是标准的——从副本 id 到版本整数的映射。点代表单个编辑 - 由一对
(replica id, version)
表示。版本向量中的每个条目都总结了一系列编辑或“点”。我在各种研究论文中看到了其他几种方法,它们使用与此非常相似的方法。
为了计算差异,副本会将其根版本向量发送给对等点。对等方将遍历其映射中的每个键,查看每个键的点列表。如果此点列表中的任何点未被传入版本向量“覆盖”,则必须打包与这些点关联的键和值并将其发送到对等点。
CRDT 映射是可组合的,因此可以使用 LWW(最后写入获胜)寄存器、MVV 寄存器、CRDT 集、另一个 CRDT 映射等来实现特定的值。
有三件事我不清楚。
尚不清楚为什么需要做任何特殊的事情才能获得添加获胜行为。在我看来,集合中的每个元素都将用一个点标记。当发生删除时,该项目会被标记为墓碑和一个点。因为版本向量和点会告诉我们何时发生并发更新和删除,所以我们可以简单地丢弃墓碑。
预先感谢您帮助解决这些问题。
对于 LWW 寄存器,他们可能需要存储所有点才能正确处理删除。这绝对是 Add-Wins 删除的情况 [1],但我不确定他们的 Remove-Wins 删除情况。
存储所有未被删除的事件的集合,加上全局版本向量。 (正如他们已经在做的那样。)