多人协同编辑技术记录
实现方案
1、覆盖技术
每个人在保存自己的修改时,将强制以自己的版本为主,覆盖其他人的对同一指标的修改。这样会导致的问题是无法真正意义上实现多人协同。
2、锁模式
锁模式即对共享资源进行上锁,当第一个用户对指标编辑时,将对被编辑的指标上锁,其他人无法编辑相同的指标,避免了多个人对同一资源进行修改造成的冲突产生。缺点是产生了等待时间,用户体验不友好。
3、diff模式
采用类似git的版本管理模式,多人协同编辑时使用socket/webrtc技术与服务端进行通信,用户保存修改内容时,在服务端进行差异化对比并合并,自动处理冲突。服务端完成修改后通过推送服务如Kafka,将修改后的内容推送给其他协同编辑人员。缺点是在多人同时修改同一指标项时,服务端无法处理,需要人为手动处理冲突。
4、OT算法(Operational Transformation,OT)
OT算法通过操作与转换来实现数据的一致性。在OT算法中,每个用户对数据的操作(如修改、删除等)都被记录下来,并在其他用户的客户端进行相应的转换,从而实现多个用户对同一份数据的协同编辑。
OT 算法的优点在于它可以实时地反映用户的操作,并且可以很好地处理并发冲突。弊端是OT算法需要在中心化的服务器上进行协同调度,因此对于大规模的分布式系统来说不太适用,但适合本项目。
5、CRDT算法 (commutative replicated data type,CRDT,可交换复制数据类型)
CRDT包含两种模式,一是基于操作(OP-based)的CRDT,另一种是基于状态(State-based)的CRDT。
基于状态的CRDT较容易实现,将整个CRDT的状态传输给每个副本,每个副本之间通过同步全量状态达到最终的统一状态,问题是开销可能会很大。
基于操作的CRDT只传输更新操作,所以开销很小,各个副本之间通过同步操作来达到最终一致状态。
目前协同算法底层多会采用向量时钟的模式来设计操作算法,向量时钟的基本思想是利用向量(vector)这种数据结构将全局各个节点的逻辑时间戳广播给各个节点,我们需要每个节点都能够知道其他所有节点的时间,这样就能够通过计算得到事件的因果关系。每个节点发送事件时都会将当前节点已知的所有节点时间写入到一个向量中,并附带在发送的消息中。这就是向量时钟的由来。
【参考Yjs协同框架。Yjs 本身是一个数据结构,原理是:当多人协作时,对于文档内容修改,通过中间层将文档数据转换成 CRDT 数据;通过 CRDT 进行数据数据更新这种增量的同步,通过中间层将 CRDT 的数据转换成文档数据,另一个协作方就能看到对方内容的更新。中间内容的更新是基于 Yjs 数据结构进行的,冲突处理等核心都是 Yjs 承担的,通信基于 websocket 或 webrtc,所以我们只需要简单的使用就可以实现多人协同的应用。】