承前启后:WOOTO与Wooki

114 阅读3分钟

Wooto

wooto是一种以行为atom的crdt文档模型的实现。本文不仅介绍了wooto算法,而且还提出了一种实现应用的基本架构--wooki,即将实施协同系统分为三个组成部分

  • 用户界面用于提供输入,以及将文档展示出来
  • wooto用于生成和执行操作
  • broadcast 用于接收和分发操作

wooto是以行作为atom的,事实上这个算法是Logoot的前身,Logoot在wooto的基础上去掉了对墓碑机制的依赖。

数据模型

每一个行使用元组来表示

<idl,content,degree,visibility><idl, content, degree, visibility>

其中,idl使用<siteid,logicclock><siteid, logicclock>来表示,content就是这一行里面的数据,degree是在插入行数据的时候生成的,用来表示松散的继承关系的一个数字,这个数字是wooto算法的核心参数,对其的使用决定了wooto模型是否能实现最终一致性,而visibility则用于表示是否可见,也就是用于删除操作的。

When site x generates an insert operation on page p, between lineA and lineB, it generates Insert(p, < (x, + + clockx), content, d, true >, idl(lineA), idl(lineB)) where d = max(degree(lineA), degree(lineB)) + 1.

因此 degree 的值越小,说明这一行出现的越早。下面是将插入操作应用到文档的算法:

image.png

可以看到每一轮循环都会先筛选出degree最小的行,然后从筛选得到的结果中寻找最接近 idl 的行,找到过后,再从得到的片段中重复上述循环过程,最终得到与l插入位置右侧相邻的ln,然后执行插入操作。

复杂度计算:对比WOOT算法对并发操作进行合并,WOOTO算法优化了时间复杂度,具体如下

WOOT算法

  • 筛选
    • 每一轮循环从CpC_pCnC_n之间筛选出idpid_pidnid_n范围大于等于当前片段的atoms,由于这个步骤基于位置来进行比较,也就是需要对每个atom执行pos(S,c)方法,因此这个阶段时间复杂度为O(n2)O(n^2)
    • 从筛选结果中找出id在idl两侧的atom
  • 根据这俩atoms获得新的片段,重复上述步骤 (n)

因此时间复杂度为O(n3)O(n^3)

WOOTO 算法

  • 每一轮循环从当前串中计算最小的degree,遍历找到id位于idl两侧的atom (n)
  • 以这两个atom作为新的参数重复上述步骤 (n)

因此WOOTO算法的时间复杂度为O(n2)O(n^2)

操作的产生和消息广播协议

用户对文档的操作并不会直接创建operation,wooto使用diff算法来讲文档与上一个状态的文档进行比较,计算出操作信息,这个算法详见 diff2

至于如果保证讲消息广播给P2P网络中的所有节点,并支持离线后再次同步,主要是用了两种算法

  • 由 standard probabilistic broadcast 算法改进的 lightweight probabilistic broadcast(lpbcast) 这个算法保证了消息一定被每个节点收到了,并且还支持了动态增加和减少节点,以及兼容弱网环境的影响
  • anti-entropy 算法,与lpcast结合以兼容离线后重连的场景