一句话定义:CRDT(Conflict-free Replicated Data Type,无冲突复制数据类型)是一类特殊设计的数据结构,它允许同一份数据存在多个副本、各自被独立修改,之后无论按什么顺序、以什么方式合并,所有副本最终都会收敛到完全一致的状态,而且不需要一个中心服务器来裁决"谁先谁后"。
它靠什么做到"自动和好"
关键在让操作变得可交换、可重复。生活里的比方:两个同事各自在便签上记录"今天要买什么",A 写下"牛奶",B 写下"面包",下班一对——两条都在,没矛盾。因为"增加一条"这个动作天生可交换:先加牛奶再加面包,和反过来,结果一样。
麻烦出在删除和修改上。A 删掉"牛奶",同时 B 把"牛奶"改成"酸奶"——这才叫并发冲突。CRDT 的处理办法是给每个元素一个全局唯一 ID,删除不真的抹掉,只留一个"墓碑"标记,再用一套确定的合并规则(比如取并集、取最大值、时间戳最新者胜 LWW)来裁决。规则本身被设计成满足交换律、结合律、幂等,所以合并顺序不影响最终结果。
常见的 CRDT 类型包括:G-Counter(只增计数器)、PN-Counter(可增可减)、G-Set/OR-Set(集合,后者支持删除)、LWW-Register(单值)、以及 RGA、Logoot 这类序列结构——文本协同编辑用的就是后者。
和 OT 的分岔路口
另一条经典路线是 OT(Operational Transformation,操作变换):所有编辑操作先送到中心服务器,服务器负责变换、排序、再广播。它的问题不在想法,而在实现——变换函数要为每一对操作类型单独写对,类型一多组合就爆炸,且很难形式化验证。CRDT 则把复杂度从"变换逻辑"搬到了"数据结构和元数据"上。
| 维度 | OT | CRDT |
|---|---|---|
| 是否需要中心定序 | 通常需要 | 不需要,可去中心 |
| 正确性来源 | 变换函数写对 | 数学性质保证收敛 |
| 元数据开销 | 较小 | 较大(ID、版本、墓碑) |
| 本地响应 | 常需等服务端往返 | 可本地立刻生效 |
| 典型场景 | 在线文档协作 | 离线编辑、端到端同步、多端合并 |
一句话取舍:要低开销、强中心,选 OT;要离线可用、无中心、拓扑复杂,选 CRDT,代价是内存和存储吃得更多。
对从业者意味着什么
做 AI 与工程的人会越来越多撞上这个议题:多智能体(multi-agent)共同维护一份记忆或知识库、边缘设备断网后回传状态、游戏与仿真里的状态同步、"本地优先"(local-first)软件的兴起,本质都是"多个副本怎么合"。CRDT 给了一个不用中心裁判的答案。
它也不是银弹:墓碑和版本元数据会随时间膨胀,需要垃圾回收;早期实现常被吐槽"吃内存"。具体某个库的实现细节与性能表现,以官方页面为准。
对普通人来说,意义更朴素——你在飞机上改的文档、手机和电脑上分别编辑的笔记,能自己合上而不互相覆盖,背后往往就是这类"不吵架的数据结构"在干活。
