5

revisionKeyしばらくの間、MongooseJS を使用してきました__v。これは、デフォルトでドキュメントに含まれるフィールドです。リビジョン番号の目的と、一般的にいつ更新されるかを理解しています。

__v最近、友人と「ベクター クロック」のアイデアについて話していたときに、このフィールドを持つ MongoDB と MongooseJS について言及しました。当時、これはベクトル時計のように聞こえました。しかし、ベクトルクロックについて少し読んだことがありますが、今はよくわかりません。

だから私は疑問に思っていversionKeyます.MongooseJSの属性と、__vそれがデフォルトで生成するフィールドは、ベクトルクロックと見なすことができますか? はい、またはいいえ、そしてその理由は?

4

2 に答える 2

4

私の意見では、versionKeyあなたが言及したものはベクトルクロックとは見なされません。ただし、 Lamport タイムスタンプ(または Lamport クロック)と考えることができます。

私たちが管理しているものをグローバルに見てみましょう。

ランポート タイムスタンプとベクトル クロックはどちらも、分散システムで発生するさまざまなイベントの因果関係を定義するために使用されるアルゴリズムです。つまり、共通の参照を持たないイベントを同期するために、両方のアルゴリズムが使用されます。

ランポート タイムスタンプ アルゴリズムは、プロセスごとに 1 つのカウンターを使用します (この質問の場合、ドキュメントごとに 1 つのカウンターを使用できます)。アルゴリズムは次のように機能します。

1) プロセス内でイベント (通信、変更など) が発生するたびに、カウンターが事前にインクリメントされます。

2) プロセスが他のプロセスにメッセージを送信するとき、送信したメッセージにカウンターの値を添付します。

3) プロセスが何らかの種類の通信を受信すると、カウンターがインクリメントされます (受信した値が現在のカウンター値より小さいか等しい場合)。カウンター値が現在の値より大きい場合は、受信した値に設定されます。

以下は、3 つのプロセスに適用されるアルゴリズムの例です。

3 つのプロセスのランポート タイムスタンプ

ランポートのタイムスタンプは、プロセスの最後のバージョン (またはマングースの場合はドキュメント) を判断できるすべてのプロセスに対して単一のカウンターを提供します。

versionKeyこれにより、これは、処理しているバージョンが現在のバージョンであるか、古いバージョンであるかを知ることができるメカニズムであると結論付けることができます。

Aaron Heckmannが Mongoose のバージョン管理に関するブログ投稿で指摘しているように ( Mongoose v3 part 1 :: Versioning :

バージョン 3 では、ドキュメント バージョンincrement()を手動でインクリメントするメソッドがドキュメントに追加されました。これは、配列に対する操作によって配列要素の位置が変更される可能性がある場合にも、内部的に使用されます。

versionKeyしたがって、配列であるサブドキュメントを変更しようとしていて、その配列の順序を変更している場合にのみ、そのまま使用します。

一方、Aaron は、このincrement()方法ではドキュメントのバージョンを手動で強制的にインクリメントすると述べています。ランポートのアルゴリズムを実装した場合、このメソッドを使用して、アルゴリズムの最初のルールを満たすバージョンをインクリメントできます。この場合、versionKeyをランポートのタイムスタンプとして使用します。

だから(ここにあなたの質問に対する実際の答えがあります)。versionKeyがベクトル クロックと見なされないのはなぜですか。

  • ベクトル クロックは、環境に関係する各プロセスのカウンターを使用します。ドキュメントの場合、ベクトル クロックを使用して、同じドキュメントの複数のバージョンを保持する必要があります。これにより、2 つの異なるドキュメントのバージョン番号が同じである場合に競合を解決できます。はversionKey単一の値であるため、ベクトル クロックと見なすことはできません。DynamoDB はベクトル クロックを使用してバージョンを処理します

ここに論文の抜粋があります:

Dynamo は、同じオブジェクトの異なるバージョン間の因果関係を把握するために、ベクトル クロックを使用します。ベクトル クロックは、事実上 (ノード、カウンター) ペアのリストです。1 つのベクトル クロックは、すべてのオブジェクトのすべてのバージョンに関連付けられています。オブジェクトの 2 つのバージョンが並列分岐にあるのか、それとも因果関係があるのか​​は、それらのベクトル クロックを調べることで判断できます。最初のオブジェクトのクロックのカウンタが 2 番目のクロックのすべてのノードよりも小さいか等しい場合、最初のオブジェクトは 2 番目のオブジェクトの祖先であり、忘れられる可能性があります。それ以外の場合、2 つの変更は競合していると見なされ、調整が必要です。

したがってversionKey、ベクトルクロックを考慮せず、いくつかの回避策を備えたランポートタイムスタンプと見なします。

于 2015-04-29T10:28:48.393 に答える