#key-value #instance #sync #map #service #key-value-store #reconciliation

reconcile

一个用于在多个实例间同步键值映射的协调服务

5 个版本

0.1.4 2023年11月21日
0.1.3 2023年11月16日
0.1.2 2023年11月13日
0.1.1 2023年11月13日
0.1.0 2023年11月8日

427数据结构

每月下载量 32

MIT/Apache

175KB
1.5K SLoC

reconcile-rs

Crates.io MIT licensed Apache licensed Build Status

文档

此 crate 提供了一个键值映射结构 HRTree,它可以与协调 Service 一起使用。不同的实例可以通过 UDP 通信,以高效地协调它们之间的差异。

所有数据都存储在所有实例的本地,用户可以通过插入钩子接收集合更改的通知。

该协议允许通过有限的往返次数在数百万个元素中查找差异。它还应该能够从其他实例中从头开始填充实例。

预期用途是一个可扩展的 Web 服务,具有非持久性和最终一致性的键值存储。该设计通过避免使用 Redis 等外部服务引起的任何延迟,从而实现高性能。

Architecture diagram of a scalable Web service using reconcile-rs

在代码中,它看起来像这样

let tree = HRTree::new();
let mut service = Service::new(tree, port, listen_addr, peer_net).await;
tokio::spawn(service.clone().run());
// use the reconciliation service as a key-value store in the API

HRTree

该协议的核心是由 HRTree(哈希范围树)数据结构实现的,它允许 O(log(n)) 访问、插入和删除,以及 O(log(n)) 累计哈希范围查询。后者属性使得查询两个键之间的所有键值对的累计(XORed)哈希值成为可能。

尽管我们独立提出了这个想法,但它与 2023 年 2 月在 Arxiv 上发表的一篇论文完全匹配:Aljoscha Meyer 的《基于范围的集合协调》:Range-Based Set Reconciliation

我们实现此数据结构基于我们自己编写的 B-Tree。尽管我们在这个方面投入了有限的精力,没有使用 unsafe,并需要维护更多的不变量,但我们的性能仍然在标准库中的 BTreeMap 的 2 倍范围内。

Graph of the time needed to insert N elements in an empty tree

上图显示了将N个元素插入树(初始为空)所需的时间(单位:毫秒)(纵坐标,左侧坐标轴)。注意,两个坐标轴都使用对数刻度。

我们《HRTree》实现的性能与《BTreeMap》非常接近。观察每个N值,我们发现《HRTree》的平均吞吐量是《BTreeMap》的三分之一到一半。

Graph of the time needed to insert and remove 1 element in a tree of size N

上图显示了将单个元素(及其删除)插入包含N个元素的树所需的时间(单位:纳秒)(横坐标,底部坐标轴)。注意,两个坐标轴都使用对数刻度。

值得注意的是,平均插入/删除时间仅从80纳秒增长到700秒,尽管树的规模从10增长到100万个元素。

Graph of the time needed to remove and restore 1 element in a tree of size N

上图显示了从包含N个元素的树中删除单个元素(及其恢复)所需的时间(单位:纳秒)(横坐标,底部坐标轴)。注意,两个坐标轴都使用对数刻度。

值得注意的是,平均删除/插入时间仅从100纳秒增长到800秒,尽管树的规模从10增长到100万个元素。

Graph of the time needed to compute 1 hash of a range of elements in a tree of size N

上图显示了在大小为N的树中对随机范围元素计算1个累积哈希所需的时间(单位:微秒)(横坐标,底部坐标轴)。注意,两个坐标轴都使用对数刻度。

随着树的规模从10增长到100万个元素,累积哈希的平均时间从30纳秒增长到1,200纳秒。

尽管在《HRTree》的性能方面可能还有很大的改进空间,但对于我们的目的来说已经足够,因为我们预计网络延迟会大得多。

服务

该服务利用《HRTree》的特性,在两个实例的集合中执行类似于二分搜索的搜索。一旦找到差异,就交换相应的键值对并解决冲突。

Graph of the time needed to send 1 insertion and 1 removal

上图显示了在包含相同N个元素的《Service》的两个实例之间发送1个插入操作,然后是1个删除操作所需的时间(单位:微秒)(横坐标,左侧坐标轴)。注意,两个坐标轴都使用对数刻度。

时间非常稳定,大约在122微秒左右,这表明协调时间完全受本地网络传输限制。这是由于在插入/删除时立即传输元素而实现的。

Graph of the time to reconcile 1 difference between two instances

上图显示了在包含相同其他N个元素的《Service》的两个实例之间协调1个插入操作,然后是1个删除操作所需的时间(单位:毫秒)(横坐标,左侧坐标轴)。注意,两个坐标轴都使用对数刻度。

这次,必须运行完整的协调协议来识别差异。随着集合规模的增加,时间从240微秒增长到640微秒。

注意:这些基准测试是在本地回环网络接口上执行的。在实际网络上,传输延迟会使这些值更大。

依赖关系

~167K
~167K SLoC