我已经使用MongooseJS的revisionKey已有一段时间了-默认情况下,它包含在文档中的__v字段。我了解修订版本号的用途,以及通常在什么时候进行更新。

我最近与一位 friend 谈论了“矢量时钟”的概念,我提到了具有此__v字段的MongoDB和MongooseJS。当时,听起来好像是矢量时钟。但是,我已经阅读了一些有关矢量时钟的内容,但现在不确定。

所以我想知道:MongooseJS的versionKey属性及其默认生成的__v字段是否可以视为矢量时钟?是或否,为什么?

最佳答案

我认为您提到的versionKey不能视为矢量时钟。您可以将其视为Lamport timestamp(或Lamport Clock)。

让我们对我们正在管理的内容有一个整体的了解:

Lamport时间戳和矢量时钟都是用于定义分布式系统中发生的不同事件的因果关系顺序的算法。换句话说,两种算法都用于同步没有共同引用的事件。

Lamport时间戳算法为每个过程使用一个计数器(在问题的情况下,我们可以为每个文档说一个计数器)。该算法的工作原理如下:

1)在过程中每次发生事件(通信,修改等)时,计数器都会预先增加。

2)当一个进程向另一个进程发送消息时,它将计数器的值附加到已发送的消息上。

3)当进程接收到任何类型的通信时,计数器将递增(如果接收值小于或等于当前计数器值),或者如果计数器值大于当前值,则将计数器值设置为接收值。

这是应用于三个过程的算法示例:

Lamport时间戳为所有进程提供一个计数器,可确定哪个是进程的最后版本(或 Mongoose 案例中的文档)。

如此说来,我们可以得出结论,versionKey是一种机制,它使我们可以知道正在处理的版本是当前版本还是已经过时。

正如Aaron Heckmann在他的博客文章中指出的有关Mongoose版本控制(Mongoose v3 part 1 :: Versioning:



因此,如果试图修改作为数组的子文档并且要更改该数组的顺序,则开箱即用的格式是versionKey

另一方面,Aaron指出increment()方法手动强制增加文档版本。如果实现了兰莫特算法,则可以使用此方法来增加满足算法第一条规则的版本。在这种情况下,您将使用versionKey作为Lamport时间戳。

所以(这是您问题的实际答案)。为什么versionKey不能被视为向量时钟:

  • 矢量时钟为环境中涉及的每个进程使用一个计数器。对于文档,应使用矢量时钟来保存同一文档的多个版本。这样,只要两个不同的文档具有相同的版本号,您就可以解决冲突。由于versionKey是单个值,因此不能将其视为向量时钟。 DynamoDB使用矢量时钟来处理版本here is an interesting reading about it

  • 这是论文的摘录:



    因此,我不会将versionKey视为矢量时钟,而是将其与一些替代方法一起考虑到Lamport时间戳。

    关于mongodb - MongooseJS "versionKey"(__ v字段)是 "vector clock"吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29927512/

    10-10 13:03