CRDT Algorithm Part2

Part 2: Algorithm Techniques

假设您按照第二部分的风格选择了协作应用程序的语义。以下是将这些语义转化为实际协作应用程序的简单协议:

每个用户的状态都是一个字面的操作历史记录,即一组操作,每个操作都有一个唯一 ID(UID)。当用户执行一项操作时,他们会生成一个新的 UID,然后将操作对(id, op)添加到他们的本地操作历史记录中。为了同步他们的状态,用户可以随意共享操作对(id, op)。

例如,用户可以在配对创建后立即广播它们,定期点对点共享整个历史记录,或者运行一个巧妙的协议,只向点对点发送它缺少的配对。接收者总是会忽略多余的配对(重复的 UID)。每当用户的本地操作历史被更新(无论是通过本地操作还是远程消息)时,他们就会将语义(纯函数)应用到新的历史中,从而生成当前应用程序可见的状态。

技术问题

  1. 在操作历史记录中存储并通过网络发送的是翻译后的操作。例如,在存储和发送之前将列表索引转换为列表 CRDT 位置。
  2. 操作历史还应包括因果排序元数据——第二部分操作历史中的箭头。共享操作时,也要共享其接收到的箭头,即其直接因果前辈的 UID。
  3. 可以选择强制执行因果顺序交付,在添加完所有直接因果前辈操作后,再将接收到的操作添加到本地操作历史记录中。

一、Prerequisites 先决条件

1. Replicas and Replica IDs 副本和副本 ID

副本是单个设备上单个线程中协作应用程序状态的单个副本。对于基于网络的应用程序,每个浏览器标签页通常有一个副本;当用户(重新)加载一个标签页时,就会创建一个新的副本。

副本的重要性在于,副本内的所有操作都是按顺序进行的,其自身操作之间没有任何并发性。在创建副本时,通过生成一个随机字符串,为每个副本分配一个唯一的副本 ID 会比较方便。在统一协作状态的所有副本(包括同时创建的副本)中,副本 ID 必须是唯一的,这就是为什么副本 ID 通常是随机的,而不是在最终的副本 ID+1。

2. Unique IDs: Dots

要引用一段内容,应为其分配一个不可变的唯一 ID(UID)。UUID 可以使用,但它们很长(32 个字符),压缩效果不好。取而代之的是使用点 ID:形式为(replicaID, counter)的对,其中 counter 是每次递增的本地变量。因此,ID 为 “n48BHnsi” 的副本使用点 ID(“n48BHnsi”, 1)、(“n48BHnsi”, 2)、(“n48BHnsi”, 3)等。

为了灵活分配 counter 值,可以使用 Lamport 时间戳,这样 UID 也是 LWW(Last-Write-Wins)的逻辑时间戳。

3. Tracking Operation: Vector Clocks

Vector clocks 是一种具有多种用途的理论技术。在本节中,我将重点介绍最简单的一种:跟踪一组操作。

将来,副本可能想知道它已经知道哪些操作。例如:当副本收到网络信息中的新操作时,它会查询是否已经收到过该操作,如果是,则忽略它。当副本与另一个协作者(或存储服务器)同步时,它可能会首先发送它已经知道的操作的描述,这样协作者就可以跳过发送多余的操作。追踪操作历史记录的一种方法是将操作的唯一 ID 存储为一个集合: {("A84nxi", 1), ("A84nxi", 2), ("A84nxi", 3), ("A84nxi", 4), ("bu2nVP", 1), ("bu2nVP", 2)}

但是,存储 "压缩 "表示法的成本更低:

{
   
   
  "A84nxi": 4,
  "bu2nVP": 2
}
这种表示法称为 vector clock。形式上,vector clock 是一个 Map<ReplicaID, number>,它将副本 ID 发送给从该副本接收到的最大计数器值,其中每个副本按从 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值