MongoDBは4.2カーネルは、解析された - 変更ストリームを

3.6バージョンからMongoDBは変更ストリームは、MongoDBは、同期の間で増分データ移行のために使用することができ、あなたがすることもでき、MongoDBの内部修正操作のサブスクリプションの変更ストリーム容量(多くの機能強化を行う能力に4.0、4.2バージョン)をサポートし始めました他の関連システムへのMongoDBの増分のサブスクリプション・アプリケーションは、そのような新しい情報を格納するための電力プロバイダシーン、MongoDBのように、ビジネスは新たな配信順序情報に基づいて在庫管理システムに通知する必要があります。

変更ストリームコントラストテーリングOplog

あなたが取得したい場合は変更ストリーム機能する前に、修正MongoDBは、我々がし続けることができますインクリメントtailing oplog  マナーもプルoplog刻みフィルタoplogの条件を満たすようにoplogセットに対して引っ張って、その後、と。このアプローチは、シーンのほとんどのニーズを満たすためにもですが、不足しています。

  1. 使用のためのより高い閾値、oplogコレクション、tailableカーソルのオープン特別なオプションについては、ユーザーのニーズ(「tailable」:真、「awaitData」:真)。
  2. TS、Hおよび他の分野の記録oplogに引っ張って、ユーザーのニーズをクラッシュアプ​​リケーションを引っ張ったときに、ユーザーは次のoplogを引っ張っていき指定された最初に配置され、再開の増分を管理する必要があります。
  3. フィルタリング結果は、プル側を行って、部分的にしかoplog加入する必要があり、例えば、DB、コレクション、または操作の種類は、次いで濾過し、左右oplogに引かれなければなりません。
  4. 更新操作の場合、oplogには、例えば、操作の一部のみが含まれている{$set: {x: 1}}アプリケーションは、多くの場合、文書の完全な内容を取得する必要がありながら、。
  5. シャードクラスタがサブスクリプションをサポートしていない、そうでなければ結果は順不同でもあり、ユーザーはoplogを尾行各シャードのために作る必要があり、このプロセスはmoveChunk操作を持つことはできません。

MongoDBの変更ストリームは、oplogをテーリング既存の問題を解決します

  1. 使いやすいが、APIの呼び出し、あなたはMongoDBのサーバー側からの増分変更を取得することができ、統一変更ストリームAPIを提供します。
  2. 統一されたスケジュール管理、以前の履歴書トークンの結果をもたらすことにジャストインタイムのAPI呼び出しで、位置を引いて、識別されたトークンの履歴書は、あなたが最後の位置から購読することができます。
  3. 結果は結果がDB、コレクション、OPERATIONTYPEおよび他の寸法のためのフィルタリングをサポートし、ネットワークトラフィックを削減、フィルタリングサーバー側のパイプラインをサポートしています。
  4. サポートfullDocument:更新のための「updateLookup」オプションは、その後、対応する文書の内容全体を返します。
  5. サポートシャードクラスタの変更サブスクリプション、APIのmongosに同じ要求は、変更を命じ、クラスタのグローバルな次元を得ることができます。

変更ストリーム戦闘

モンゴシェルに、例えば、変更ストリームを使用すると、モンゴシェルは、例えば、DB、コレクションレベルのための全体のサブスクリプションの操作をカプセル化し、非常に簡単です。

db.getMongo().watch()    订阅整个实例的修改
db.watch()               订阅指定DB的修改
db.collection.watch()    订阅指定Collection的修改
  1. 新しい接続を開始1サブスクリプション操作
mytest:PRIMARY>db.coll.watch([], {maxAwaitTimeMS: 60000})  最多阻塞等待 1分钟
  1. 新しい接続に新しいデータを書き込む2

         

mytest:PRIMARY> db.coll.insert({x: 100})
WriteResult({ "nInserted" : 1 })
mytest:PRIMARY> db.coll.insert({x: 101})
WriteResult({ "nInserted" : 1 })
mytest:PRIMARY> db.coll.insert({x: 102})
WriteResult({ "nInserted" : 1 })
  1. 1変更ストリームは、更新情報を受信するように接続しました
mytest:PRIMARY> db.watch([], {maxAwaitTimeMS: 60000})
{ "_id" : { "_data" : "825E0D5E35000000012B022C0100296E5A1004EA4E00977BCC482FB44DEED9A3C2999946645F696400645E0D5E353BE5C36D695042C90004" }, "operationType" : "insert", "clusterTime" : Timestamp(1577934389, 1), "fullDocument" : { "_id" : ObjectId("5e0d5e353be5c36d695042c9"), "x" : 100 }, "ns" : { "db" : "test", "coll" : "coll" }, "documentKey" : { "_id" : ObjectId("5e0d5e353be5c36d695042c9") } }
{ "_id" : { "_data" : "825E0D5E37000000012B022C0100296E5A1004EA4E00977BCC482FB44DEED9A3C2999946645F696400645E0D5E373BE5C36D695042CA0004" }, "operationType" : "insert", "clusterTime" : Timestamp(1577934391, 1), "fullDocument" : { "_id" : ObjectId("5e0d5e373be5c36d695042ca"), "x" : 101 }, "ns" : { "db" : "test", "coll" : "coll" }, "documentKey" : { "_id" : ObjectId("5e0d5e373be5c36d695042ca") } }
{ "_id" : { "_data" : "825E0D5E39000000012B022C0100296E5A1004EA4E00977BCC482FB44DEED9A3C2999946645F696400645E0D5E393BE5C36D695042CB0004" }, "operationType" : "insert", "clusterTime" : Timestamp(1577934393, 1), "fullDocument" : { "_id" : ObjectId("5e0d5e393be5c36d695042cb"), "x" : 102 }, "ns" : { "db" : "test", "coll" : "coll" }, "documentKey" : { "_id" : ObjectId("5e0d5e393be5c36d695042cb") } }

 

  1. あなたは時間を見て、特定の位置から、サブスクリプションを維持したい場合はChangeStream以上の結果、コンテンツ_idフィールドが再開トークンで、識別oplogの場所は、あなたがresumeAfterで指定することができます。例えば、各アプリケーションは、次の次の2つに再度加入する購読初めてトークン再開を指定し、3つの変更の上に加入したが、最初既に消費されています。

    

mytest:PRIMARY> db.coll.watch([], {maxAwaitTimeMS: 60000, resumeAfter: { "_data" : "825E0D5E35000000012B022C0100296E5A1004EA4E00977BCC482FB44DEED9A3C2999946645F696400645E0D5E353BE5C36D695042C90004" }})
{ "_id" : { "_data" : "825E0D5E37000000012B022C0100296E5A1004EA4E00977BCC482FB44DEED9A3C2999946645F696400645E0D5E373BE5C36D695042CA0004" }, "operationType" : "insert", "clusterTime" : Timestamp(1577934391, 1), "fullDocument" : { "_id" : ObjectId("5e0d5e373be5c36d695042ca"), "x" : 101 }, "ns" : { "db" : "test", "coll" : "coll" }, "documentKey" : { "_id" : ObjectId("5e0d5e373be5c36d695042ca") } }
{ "_id" : { "_data" : "825E0D5E39000000012B022C0100296E5A1004EA4E00977BCC482FB44DEED9A3C2999946645F696400645E0D5E393BE5C36D695042CB0004" }, "operationType" : "insert", "clusterTime" : Timestamp(1577934393, 1), "fullDocument" : { "_id" : ObjectId("5e0d5e393be5c36d695042cb"), "x" : 102 }, "ns" : { "db" : "test", "coll" : "coll" }, "documentKey" : { "_id" : ObjectId("5e0d5e393be5c36d695042cb") } }

内部変更ストリーム達成します

時計()のラッパー

db.watchは()APIラッパーは、実際には、MongoDBの内部の変更ストリームは、実際に集約コマンドは、単に特別な追加され、実際に$changestream  参照)(db.currentOpによって変更ストリームのサブスクリプションの操作を、開始した後、ステージ凝集/ getMore対応する操作の詳細なパラメータ。

{
      "op" : "getmore",
      "ns" : "test.coll",
      "command" : {
        "getMore" : NumberLong("233479991942333714"),
        "collection" : "coll",
        "maxTimeMS" : 50000,
        "lsid" : {
          "id" : UUID("e4fffa71-e168-4527-be61-f0918849d107")
        },
      },
      "planSummary" : "COLLSCAN",
      "cursor" : {
        "cursorId" : NumberLong("233479991942333714"),
        "createdDate" : ISODate("2019-12-31T06:35:52.479Z"),
        "lastAccessDate" : ISODate("2019-12-31T06:36:09.988Z"),
        "nDocsReturned" : NumberLong(1),
        "nBatchesReturned" : NumberLong(1),
        "noCursorTimeout" : false,
        "tailable" : true,
        "awaitData" : true,
        "originatingCommand" : {
          "aggregate" : "coll",
          "pipeline" : [
            {
              "$changeStream" : {
                "fullDocument" : "default"
              }
            }
          ],
          "cursor" : {

          },
          "lsid" : {
            "id" : UUID("e4fffa71-e168-4527-be61-f0918849d107")
          },
          "$clusterTime" : {
            "clusterTime" : Timestamp(1577774144, 1),
            "signature" : {
              "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
              "keyId" : NumberLong(0)
            }
          },
          "$db" : "test"
        },
        "operationUsingCursorId" : NumberLong(7019500)
      },
      "numYields" : 2,
      "locks" : {

      }
    }

トークン再開

レジューム加入トークン点を説明するために使用され、サブスクリプションAPIベルト再開トークン、MongoDBのサーバーは、トークンは、対応する情報に変換するclusterTime、UUID、documentKey情報を含むパッケージoplog情報は、本質的であり、そして検索します継続的なサブスクリプション操作のための出発点oplog。

struct ResumeTokenData {
    Timestamp clusterTime;
    int version = 0;
    size_t applyOpsIndex = 0;
    Value documentKey;
    boost::optional<UUID> uuid;
};

4.0.7新発売再開トークン形式、バージョン1;さらにバージョン3.6、再開トークン符号化し、また4.0 ResumeTokenData構造は、バージョン情報、以前のバージョン4.0.7、バージョンは0が含まれてい異なるが、そのアップグレード後、トークンの異なるバージョンに問題があるかもしれないので、すべてのコンポーネントのMongoDBサーバ(レプリカセットの各メンバー、CONFIGSERVER、mongosは)同じカーネルバージョンのままにしようと、認識されていません。

より詳細な情報、参照してくださいhttps://docs.mongodb.com/manual/reference/method/Mongo.watch/#resumability

updateLookup

などだけではなく、操作自体を更新する更新操作のための変更ストリームサポート、ドキュメントの現在のフルコンテンツを取得するために、

mytest:PRIMARY> db.coll.find({_id: 101})
{ "_id" : 101, "name" : "jack", "age" : 18 }
mytest:PRIMARY> db.coll.update({_id: 101}, {$set: {age: 20}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

上記の更新操作は、デフォルトでは、変更ストリームが受信する {_id: 101}, {$set: {age: 20}  コンテンツを、この分野の他の情報が含まれていないが、文書を更新されません。そしてfullDocumentを追加:「updateLookup」オプションの後、変更ストリームは、文書の_idに応じて移動します文書とリターンの現在の内容を検索します。

注updateLookupオプションのみが、このような上記の文書のように最終的な一貫性を保証することができ、その、連続100回を更新した場合、すべての時間は、ドキュメントを検索するため、変更ストリームではなく、中央の更新を毎回受け取るためにを更新現在のコンテンツ、及び現在の内容は、後続の変更によって覆われていてもよいです。

シャードクラスタ

シャードクラスタの変更ストリーム・サポート・サブスクリプション、そのグローバルかつ秩序リターン結果を保証します。この目標にグローバルな秩序を達成するために、mongosは、各シャードのマージからの戻り結果をサブスクライブする必要が返されるタイムスタンプでソートされました。

極端な例では、書き込みの量いくつかの破片のほとんど、あるいはまったく記述する場合、変更ストリームドロップアウト遅延があるため、すべてのシャードを返すのサブスクリプションが得られるまで待つ必要で、影響を受けることになります。デフォルトでは、のmongodサーバーでは、すべての10sが生成されますNOOP oplog特別には、このメカニズムは、間接的に高く、それを操作し続けることができていない書かれた量でシャードクラスタを駆動します。

シャードクラスタを書かれた大音量で、並べ替えのための世界的な必要性として、変更ストリームのパフォーマンスはおそらく追いつくことがあり、性能要件が非常に高い場合は、各シャード上で、独自の変更ストリームを確立するために、バランサを閉じて考えることができます。

参考資料

おすすめ

転載: yq.aliyun.com/articles/741514