Является ли MongooseJS "versionKey" (поле __v) "векторными часами"?

Я использую MongooseJS revisionKey на некоторое время сейчас - __v поле, которое оно включает в документы по умолчанию. Я понимаю, какова цель номера ревизии и вообще когда она обновляется.

Недавно я говорил с другом об идее "векторных часов", и я упомянул, что у MongoDB и MongooseJS есть такая __v поле. В то время казалось, что это могут быть векторные часы. Но прочитав немного о векторных часах, теперь я не уверен.

Так что мне интересно: может ли versionKey атрибут MongooseJS, а также __v Поле, которое оно выдает по умолчанию, будет считаться вектором часов? Да или нет и почему?

2 ответа

Решение

По моему мнению versionKey Вы упоминаете, нельзя считать векторные часы. Вы могли бы рассмотреть это метка времени Лампорта (или Часы Лампорта) все же.

Давайте посмотрим глобально на то, что мы управляем:

И метки времени Лампорта, и векторные часы являются алгоритмами, используемыми для определения порядка причинности для различных событий, происходящих в распределенной системе. Другими словами, оба алгоритма используются для синхронизации событий, которые не имеют общей ссылки.

Алгоритм временных меток Lamport использует один счетчик для каждого процесса (в случае вопроса мы можем сказать один счетчик для каждого документа). Алгоритм работает следующим образом:

1) Каждый раз, когда в процессе происходит событие (связь, модификация и т. Д.), Счетчик предварительно инкрементируется.

2) Когда процесс отправляет сообщение другому процессу, он присоединяет значение счетчика к отправленному сообщению.

3) Когда процесс получает какую-либо связь, счетчик увеличивается (если полученное значение меньше или равно текущему значению счетчика) или значение счетчика устанавливается равным полученному значению, если оно больше текущего значения.

Вот пример алгоритма, примененного к трем процессам:

Временные метки Лампорта для трех процессов

Временные метки Лампорта предлагают единый счетчик для всех процессов, который позволяет определить, какая версия процесса является последней (или документ в случае с мангустом).

С учетом сказанного можно сделать вывод, что versionKey это механизм, который позволяет нам узнать, является ли версия, с которой мы имеем дело, текущей или мы устарели.

Как отмечает Аарон Хекманн в своем блоге о версии в Mongoose ( Mongoose v3 часть 1:: Управление версиями:

В версии 3 документы теперь имеют increment() метод, который вручную форсирует увеличение версии документа. Это также используется внутри системы всякий раз, когда операция над массивом потенциально меняет положение элемента массива.

Таким образом, из коробки вы будете использовать только versionKey если вы пытаетесь изменить вложенный документ, который является массивом, и вы меняете порядок этого массива.

С другой стороны, Аарон утверждает, что increment() Метод вручную форсирует увеличение версии документа. Если вы реализовали алгоритм Лампорта, вы можете использовать этот метод для увеличения версии, соответствующей первому правилу алгоритма. В этом случае вы будете использовать versionKey в качестве метки времени Лампорта.

Итак (вот вам и актуальный ответ на ваш вопрос). Почему versionKey нельзя считать векторными часами:

  • Векторные часы используют счетчик для каждого процесса, вовлеченного в окружающую среду. В случае документов векторные часы должны использоваться для хранения нескольких версий одного и того же документа. Это позволяет разрешать конфликты, когда два разных документа имеют одинаковый номер версии. Как versionKey это одно значение, оно не может рассматриваться как векторные часы. DynamoDB использует векторные часы для обработки версий, вот интересное чтение об этом

Вот выдержка из бумаги:

Динамо использует векторные часы, чтобы уловить причинно-следственную связь между различными версиями одного и того же объекта. Векторные часы фактически являются списком пар (узел, счетчик). Один вектор часов связан с каждой версией каждого объекта. Можно определить, находятся ли две версии объекта на параллельных ветвях или имеют причинное упорядочение, изучив их векторные часы. Если счетчики на часах первого объекта меньше или равны всем узлам на вторых часах, то первый является предком второго и может быть забыт. В противном случае оба изменения считаются конфликтующими и требуют согласования.

Так что я бы не стал рассматривать versionKey векторные часы, и я буду считать это меткой времени Лампорта с некоторыми обходными путями.

Я понимаю, что versionKey значение увеличивается только на save а также findOneAndUpdate функции. Так как versionKey значение не увеличивается, когда update выполняется, или когда выполняется ручное обновление с использованием Mongo Cli, я считаю, что это не пройдет тест для определения векторных часов.

Другие вопросы по тегам