我一直在阅读CvRDTs,我知道Riak已经added a few向Riak 2。
我的问题是:当听起来与每个对象关联的基础vclock
记录相同信息时,为什么Riak会实现gcounter
?结果不是gcounter
存储vclock
,每个都包含相同的基本信息吗?
我现在唯一的猜测是,Riak可能会垃圾收集vclocks
,修剪对于gcounter
而言实际上很重要的信息(即增量数)。
我无法特别好地阅读Erlang,所以也许我错误地认为Riak存储vclocks
这些特殊情况数据类型。但是,问题仍然适用于在标准Riak之上编写的homegrown solutions(因此在每个对象持久化的情况下继承vclocks
。)
修改
我已经写了以下文章,以更实际的方式帮助解释CvRDT。本文还涉及我上面强调的冗余:
Conflict-free Replicated Data Types (CRDT) - A digestible explanation with less math.
答案 0 :(得分:4)
Riak修剪版本载体,因果关系(假并发,更多兄弟姐妹,安全)没什么大不了的,但却是柜台的灾难。
Riak的CRDT支持很普遍。我们将CRDT“隐藏”在常规riak对象中。
Riak的CRDT支持是它的第一波,我们将在进一步发布时进一步优化。
我们有一个很棒的邮件列表,可以解决这个问题,顺便说一句。 Stack Overflow有它的用途,但如果你想与开源数据库的作者交谈,为什么不使用他们的列表呢?由于Riak是开源的,您可以提交拉取请求,我们很乐意将您的想法融入代码库。
答案 1 :(得分:2)
快速回答: Riak的计数器实际上是PN计数器,即它们允许递增和递减,因此不能像vclock那样实现,因为它们需要跟踪增量和减量的不同。 / p>
长答案:
这个问题表明你完全误解了g计数器和矢量时钟(或版本矢量)之间的区别。
矢量时钟(vclock)是用于跟踪对一条数据的并发更新的因果关系的系统。它们是{actor =>的地图逻辑时钟}。演员只有在与其关联的数据发生变化时才会增加逻辑时钟,并尝试尽可能少地增加它们(因此每次更新最多一次)。两个vclocks可以是并发的,也可以是另一个。
g-counter是一个CvRDT,看起来与vclock的结构相同,但有重要区别。它们被实现为{actor =>的地图计数器}。演员可以根据需要增加自己的计数器。 g计数器具有“计数器值”的概念,以及“合并”的概念,因此当并发操作由不同的参与者执行时,它们可以计算出实际的“计数器值”应该是什么。
重要的是,g-counter无法追踪因果关系,而vclocks也不知道他们的“反价值”是什么。
将两者混合在代码库中不仅会造成混淆,而且还会带来错误。
将此添加到riak实际实现pn计数器的事实中。不同之处在于g计数器只能递增,但pn计数器可以递增和递减。 Pn计数器的工作方式是{actor => (增量计数,减量计数)},这显然与vclock具有不同的结构。你只能增加这两个数,所以为什么有两个而不只是一个。