协同编辑指的是多个用户可以同时对同一文档进行编辑,并确保所有用户看到的内容保持一致。它的核心挑战是如何处理多个用户的并发操作,避免冲突并确保最终一致性。
OT 通过对操作进行转换来处理并发编辑。它提供了一种操作转换器,能够在出现“脏路径”(多个用户的操作依赖于编辑的路径,同样的编辑操作如果顺序不同会导致结果不同)时,将并发操作进行调整。OT 的主要步骤包括:
下图是 OT 解决「脏路径」和「并发冲突」的直观理解。
CRDT 即 「无冲突复制数据类型」,它主要被应用在分布式系统中,保证分布式应用的数据一致性,文档协同编辑可以理解为分布式应用的一种。它的本质是数据结构,通过数据结构的设计保证并发操作数据的最终一致性。
与 OT 不同,CRDT 不需要依赖复杂的操作转换机制,而是通过数学上的设计确保所有用户对数据的修改可以无冲突地合并,最终达成一致性。
大多数的 CRDT 为在文档中创建的每个字符分配一个唯一的标识符。为了确保文档始终能够收敛,CRDT 模型即使在删除字符时也会保留元数据。
CRDT 最初是为了解决分布式系统最终数据一致性而提出的,它支持各个主机副本之间数据修改的直接同步,而且数据修改的同步顺序以及同步的次数不影响最终结果,只要修改操作一致,数据的最终状态就是一致的,也就是通常大家说的 CRDT 数据的满足交换性和幂等性。
下面用一个例子来说明 CRDT 的工作原理,主要体现修改的顺序对最终结果没有影响。
我们设计一种编辑的表达方式 作为一个操作的标识, 表示操作的作者编号, 表示操作的序号。对于每个编辑,都有一个全局唯一的 id,这个 id 由作者编号和序号组成。对同样的编辑 id 集合,无论他们的顺序如何,最终的结果都是一样的。
在上面的图片中,原本的文本是 AB
,用户 0 在 AB 中间插入一个字符 C
,接着在 C
后面插入一个字符 D
,得到 ACDB
。但同时用户 1 并发的在 AB
中间插入一个字符 E
,此时,在拿到这三个编辑的集合后,我们通过一些规则来合并这些编辑操作,比如用户 1 的用户编号比用户 0 的大,那么可以把所有用户 1 的操作排在用户 0 的操作后面,最终的结果是 ACDEB
。
CRDT 有着极佳的去中心化性质,它在 Web 3.0 时代或许有机会成为某种形式的前端基础设施。并且相对于经典的 OT,近年来 CRDT 的流行或许也属于一次潜在的范式转移(paradigm shift),这对前端开发者们意味着全新的机遇。 同时,CRDT比较适合来记录用户产生的各种事件的集合,因此将这些事件直接用于推荐系统的计算也是自然而然的事情。特别是对于很多大规模的企业,需要将用户的数据分布在多个数据中心,必须要实现读写两方面的高可用,特别是一些边缘计算的场景,可以利用CRDT的去中心化、离线、无冲突等特性实现用户操作数据的收集和同步。