问题标签 [crdt]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
688 浏览

distributed-computing - CRDT 和 RAFT 协议之间是否存在关系——或者它们是正交的?

以多人网络游戏的用例为例。您会立即遇到跨网络复制和协调共享状态的问题。

针对这个问题的方面似乎有多种工具,特别是两个似乎重叠:

  1. 无冲突复制数据类型(CRDT) - 用于
  2. RAFT 共识算法- 用于在分布式网络中选择交易领导者以帮助达成共识。

我的问题是:CRDT 和 RAFT 协议之间是否存在关系——或者它们是正交的?

0 投票
1 回答
64 浏览

ruby - Riak ruby​​ 客户端尝试删除 CRDT 映射

将 ruby​​ 客户端 (2.3.0) 与 Riak 2.0 一起使用。我创建了一个 CRDT 存储桶类型的“地图”,它存储(惊喜)地图。

一切正常,包括搜索等,但对于我来说,当我不再需要地图时,我无法弄清楚如何删除它。

我已经根据我发现的东西尝试了这个:

这不会给出错误,但地图不会从 Riak 中删除;它也不是“墓碑”,因为我仍然可以从中检索数据,并且搜索索引也仍然有数据。

我也试过:

但这也不起作用。它给出了错误“没有将符号隐式转换为整数”并且没有“映射”它也不起作用。

查看控制台中的第一个选项,在我看来它正在访问正确的对象,但对其调用“删除”似乎没有任何效果。

如何正确删除地图?至少如果我可以将它从索引结果中删除将是一大步!

谢谢

0 投票
1 回答
63 浏览

erlang - 用于在服务器上的 Map CRDT 中设置/更新注册字段的语法

在 Riak 的服务器端设置lwwreg寄存器值的语法是什么?CRDT Map我尝试了如下似乎无效的代码:

我收到有关操作无效的错误 - 我查看了源代码riak_dt_map.erl但仍然无法找出正确的语法:

将欣赏有关正确语法的指针。

0 投票
1 回答
92 浏览

elixir - Riak KV 中标志的上下文与什么有关

在 Riak KV 中使用标志时,标志需要上下文。在 Elixir 客户端中,上下文由 设置Flag.new("my context"),否则会:context_required在尝试禁用标志时抛出。

现在,flag 只能存在于一个 Map 中,并且 map 中的每个元素都必须有一个 key,因此多个 flag 可以在一个 Map 中,仍然可以通过 key 来区分。

如果不区分它们,上下文的目的是什么?

0 投票
1 回答
956 浏览

distributed-computing - 哪些 CRDT 可用于实现功能齐全的协作富文本编辑器?

我一直在研究 CRDT,了解到它们已被用于构建协作编辑器,包括Ritzy、TreeDoc、WOOT 和 Logoot。

我对构建这样的编辑器很感兴趣,并且需要知道 CRDT 是否能够在一般情况下处理这个问题。

详细说明:富文本文档(想想 html)具有树结构,但节点是异构的。有块元素、行内元素、表格、列表等。此外,文档中可能嵌入了样式和样式表(例如 css)。最后,撤消是必不可少的。

上面列出的编辑器不处理更高级的功能,例如表格、嵌入式样式表和撤消/重做。

Ritzy 文档链接到描述基于 CRDT 的因果树的论文 ( pdf ),但我并不真正理解这篇论文。

因果树 CRDT 背后的基本原理是什么?处理上述异构树是否足够强大?或者,是否有其他 CRDT 可以处理这种情况?

0 投票
1 回答
186 浏览

erlang - 将 Riak CRDT 与 bitcask 后端一起使用

我在配置 CRDT 存储桶类型和使用 bitcask 后端时遇到问题。我希望能够使用 set 类型并保持 bitcask 到期的功能。

如果我不指定后端,我可以创建和使用存储桶类型

但是如果我尝试在 props 中指定一个后端,那么每当我尝试使用该类型时,riak 似乎就会崩溃并且我失去了连接。

这是我尝试使用存储桶类型时 error.log 中的唯一日志。如果有帮助,我还尝试将后端指定为 leveldb 和 memory 以及 bitcask,但没有成功。

2016-10-13 13:41:25.965 [错误] <0.8870.0> gen_fsm <0.8870.0> 处于活动状态,因原因终止:在 riak_core_vnode 中没有匹配 {riak_kv_multi_backend、undefined_backend、<<"bitcask">>} 的案例条款:vnode_command/3 line 346 2016-10-13 13:41:25.965 [error] <0.8870.0> CRASH REPORT 进程 <0.8870.0> 有 1 个邻居退出,原因是:没有匹配 {riak_kv_multi_backend,undefined_backend,<< “bitcask”>>} in riak_core_vnode:vnode_command/3 line 346 in gen_fsm:terminate/7 line 622 2016-10-13 13:41:25.965 [error] <0.168.0> Supervisor riak_core_vnode_sup 有子 undefined 从 {riak_core_vnode, start_link,undefined} 在 <0.8870.0> 退出,原因是没有 case 子句匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} in riak_core_vnode:vnode_command/3 line 346 in context child_terminated 2016-10-13 13:41:25.965 [error] <0.8896.0> gen_fsm <0.8896.0> in state ready terminate with reason: no case Clause match {riak_kv_multi_backend, undefined_backend,<<"bitcask">>} in riak_core_vnode:vnode_command/3 line 346 2016-10-13 13:41:25.965 [error] <0.8896.0> CRASH REPORT Process <0.8896.0> 有 10 个邻居因原因退出:在 riak_core_vnode:vnode_command/3 第 346 行中 gen_fsm:terminate/7 第 622 行中没有匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} 的 case 子句 2016-10-13 13:41:25.966 [错误] <0.8897。 0> 主管 {<0.8897.0>,poolboy_sup} 有子 riak_core_vnode_worker 以 riak_core_vnode_worker:start_link([{worker_module,riak_core_vnode_worker},{worker_args,[1370157784997721485815954530671515330927436759040,...]},...]) 在未定义退出,原因是没有 case 子句匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} 在 riak_core_vnode:vnode_error/3 line 346 in context shutdown 2016-10-13 13:41:25.966 [错误] <0.8897.0> gen_server <0.8897.0> 因原因终止:在 riak_core_vnode:vnode_command/ 中没有匹配 {riak_kv_multi_backend、undefined_backend、<<"bitcask">>} 的 case 子句3 line 346 2016-10-13 13:41:25.966 [error] <0.8897.0> CRASH REPORT Process <0.8897.0> with 0 个邻居退出,原因是:没有匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask" 的 case 子句>>} in riak_core_vnode:vnode_command/3 line 346 in gen_server:terminate/6 line 744[1370157784997721485815954530671515330927436759040,...]},...]) 在未定义退出时,原因是没有 case 子句匹配 riak_core_vnode:vnode_command/3 line 346 in context shutdown_error 201-error 201-6 -13 13:41:25.966 [错误] <0.8897.0> gen_server <0.8897.0> 因原因终止:在 riak_core_vnode:vnode_command/3 第 346 行中没有匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} 的 case 子句2016-10-13 13:41:25.966 [错误] <0.8897.0> 崩溃报告进程 <0.8897.0> 有 0 个邻居退出,原因是:没有匹配 {riak_kv_multi_backend、undefined_backend、<<"bitcask">>} 的案例子句在 riak_core_vnode:vnode_command/3 第 346 行 gen_server:terminate/6 第 744 行[1370157784997721485815954530671515330927436759040,...]},...]) 在未定义退出时,原因是没有 case 子句匹配 riak_core_vnode:vnode_command/3 line 346 in context shutdown_error 201-error 201-6 -13 13:41:25.966 [错误] <0.8897.0> gen_server <0.8897.0> 因原因终止:在 riak_core_vnode:vnode_command/3 第 346 行中没有匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} 的 case 子句2016-10-13 13:41:25.966 [错误] <0.8897.0> 崩溃报告进程 <0.8897.0> 有 0 个邻居退出,原因是:没有匹配 {riak_kv_multi_backend、undefined_backend、<<"bitcask">>} 的案例子句在 riak_core_vnode:vnode_command/3 第 346 行 gen_server:terminate/6 第 744 行..])在未定义退出时,原因没有 case 子句匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} in riak_core_vnode:vnode_command/3 line 346 in context shutdown_error 2016-10-13 13:41:25.966 [错误] <0.8897.0> gen_server <0.8897.0> 因原因终止:在 riak_core_vnode:vnode_command/3 行 346 2016-10-13 13:41:25.966 中没有匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} 的 case 子句[错误] <0.8897.0> CRASH REPORT 进程 <0.8897.0> 有 0 个邻居退出,原因是:没有 case 子句匹配 riak_core_vnode 中的 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>}:vnode_command/3 line 346 in gen_server :terminate/6 第 744 行..])在未定义退出时,原因没有 case 子句匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} in riak_core_vnode:vnode_command/3 line 346 in context shutdown_error 2016-10-13 13:41:25.966 [错误] <0.8897.0> gen_server <0.8897.0> 因原因终止:在 riak_core_vnode:vnode_command/3 行 346 2016-10-13 13:41:25.966 中没有匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} 的 case 子句[错误] <0.8897.0> CRASH REPORT 进程 <0.8897.0> 有 0 个邻居退出,原因是:没有 case 子句匹配 riak_core_vnode 中的 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>}:vnode_command/3 line 346 in gen_server :terminate/6 第 744 行undefined_backend,<<"bitcask">>} in riak_core_vnode:vnode_command/3 line 346 in context shutdown_error 2016-10-13 13:41:25.966 [error] <0.8897.0> gen_server <0.8897.0> 终止原因:否在 riak_core_vnode:vnode_command/3 行 346 2016-10-13 13:41:25.966 [error] <0.8897.0> CRASH REPORT Process <0.8897.0> 中匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} 的 case 子句有 0 个邻居退出,原因是:在 riak_core_vnode:vnode_command/3 line 346 in gen_server:terminate/6 line 744 中没有匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} 的 case 子句undefined_backend,<<"bitcask">>} in riak_core_vnode:vnode_command/3 line 346 in context shutdown_error 2016-10-13 13:41:25.966 [error] <0.8897.0> gen_server <0.8897.0> 终止原因:否在 riak_core_vnode:vnode_command/3 行 346 2016-10-13 13:41:25.966 [error] <0.8897.0> CRASH REPORT Process <0.8897.0> 中匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} 的 case 子句有 0 个邻居退出,原因是:在 riak_core_vnode:vnode_command/3 line 346 in gen_server:terminate/6 line 744 中没有匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} 的 case 子句8897.0> 因原因终止:在 riak_core_vnode:vnode_command/3 行 346 2016-10-13 13:41:25.966 [错误] <0.8897.0> 中没有匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} 的案例条款报告进程 <0.8897.0> 与 0 个邻居退出,原因是:没有 case 子句匹配 riak_core_vnode:vnode_command/3 第 346 行中的 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} gen_server:terminate/6 第 744 行8897.0> 因原因终止:在 riak_core_vnode:vnode_command/3 行 346 2016-10-13 13:41:25.966 [错误] <0.8897.0> 中没有匹配 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} 的案例条款报告进程 <0.8897.0> 与 0 个邻居退出,原因是:没有 case 子句匹配 riak_core_vnode:vnode_command/3 第 346 行中的 {riak_kv_multi_backend,undefined_backend,<<"bitcask">>} gen_server:terminate/6 第 744 行<<"bitcask">>} in riak_core_vnode:vnode_command/3 line 346 in gen_server:terminate/6 line 744<<"bitcask">>} in riak_core_vnode:vnode_command/3 line 346 in gen_server:terminate/6 line 744

我正在使用 Riak v2.0.7 LTS

0 投票
1 回答
170 浏览

p2p - 为什么 logoot 方法需要时钟?

我正在计划一个 P2P 协作编辑软件,我正计划使用 WOOT。问题是我会有大量的墓碑(原子是字符......)所以我搜索了更多并找到了这个关于 Logoot 方法的 PDF。除了一件事,我很清楚:为什么每个站点都需要时钟?我在文档中找不到任何提及此值用途的内容。

是否存在需要解决时钟而不发生冲突的情况?

0 投票
1 回答
927 浏览

algorithm - Logoot CRDT:将并发编辑的数据交错到同一个位置?

我想为最终收敛的 P2P 文本编辑实现Logoot,但我遇到了一些问题。

我对 Logoot 的理解是,对象之间的间隔(原论文中的文本行,但可以是字符或单词)可以由于无界标识符而无限分割。这意味着一个对象的位置不是由它的邻居决定,就像在 WOOT 中那样(这将需要墓碑),而是由沿着字符串长度的固定数字点决定。结合唯一的站点标识符,这也为我们提供了一个完整的顺序并实现了最终的融合。

但是......当对同一地点进行并发编辑时,这不会导致问题吗?如果两个断开连接的客户端开始在相同的光标位置写新句子然后合并,他们的句子有很好的交错机会。

下面是我正在谈论的白板示例:

白板

可以看到,站点 B 和站点 C 都按照 Logoot 的规则划分了“我”和“征服”之间的区间,给了我们在 (20,A) 和 (25,A) 的位置之间的随机点。但是没有任何东西可以相对于彼此对这些点进行排序,从而导致它们在合并时混合。同时,基于邻居的算法可以解决这个问题,因为每个对象的因果链都被保留了。

上面是一个小例子,但在更一般的情况下,想象一下如果两个用户想要在两个现有句子之间插入一个不同的句子。如果其中一个用户恰好离线,他们不应该回到乱码!显然,为了保持意图,一个句子应该在另一个句子之后。

我在阅读论文时是否遗漏了什么,或者这是 Logoot 的固有缺点?

(另外,为什么在算法中似乎没有使用记录的时钟值?论文甚至指出,每个对象的标识符在没有时钟的情况下必然是唯一的。)

0 投票
1 回答
446 浏览

akka - 为什么 akka 中的 gossip 协议需要两次传递它的状态才能注册状态更改?

我无法理解 Akka 中使用的集群算法。

在 akka Gossip Protocol的描述中,它说:

gossip 状态或 gossip 状态的接收者可以使用 gossip 版本(向量时钟)来确定是否:

  1. 它有一个更新版本的 gossip 状态,在这种情况下,它会将它发送回 gossiper
  2. 它有一个过时的状态版本,在这种情况下,接收者通过发回它的八卦状态版本来向八卦者请求当前状态
  3. 它有相互冲突的八卦版本,在这种情况下,不同的版本被合并并发回

第二步似乎浪费了通信,因为 gossiper 发送了两次它的状态。一次是当它发现它没有最新版本时,再一次是当接收者通过发回自己的过时版本来想要最新版本时。

我认为我对此有误解,因为我对矢量时钟和 CFRD 的理解有限,并且 Akka 文档中给出的描述很短,而维基百科的文章是高级的。就我而言,矢量时钟是 CRDT 的一种实现,但这可能是不正确的。

但最后我不明白为什么八卦节点需要两次传达其状态。请说清楚。

但我想我可能误解了vector Akka Cluster

0 投票
2 回答
454 浏览

data-structures - 添加/删除集 CRDT 是单调的吗?

添加/删除集 CRDT 的内部是单调的,因为我们只添加到内部集,因此 CRDT 的内部状态永远不会在逻辑时间上倒退。

但是,CRDT 的观察状态是我们正在添加和删除元素,因此观察到的状态不必是单调的。

如果我们将这些系统链接在一起并根据元素的存在或不存在采取行动,它看起来就不再单调了。最终状态最终仍会收敛,但在它稳定之前我们可能会或可能不会看到一些元素。由于该中间状态而发生某些副作用的可能性不大,例如用户读取系统状态并在其收敛之前做出反应。

CRDT 是单调的意味着什么?