web-dev-qa-db-ja.com

MongoDB挿入パフォーマンスを向上させる方法

結果:

フォールトトレラントなデータセットを操作している場合、または確認できる1回限りのプロセスを実行している場合は、WriteAcknowledgeをUnacknowledgedに変更すると役立ちます。

また、一括操作はデフォルトでIsOrderedであり、私は気づいていませんでした。これをFalseに設定すると、実際には操作が一括で実行されます。それ以外の場合は、更新の1つのスレッドとして機能します。


MongoDB 3.0/WiredTiger/C#ドライバー

私は1億4700万のドキュメントを含むコレクションを所有しており、そのうち約1秒(うまくいけば)毎秒更新を実行しています。 3000ドキュメント。

更新の例を次に示します。

_"query" : {
    "_id" : BinData(0,"UKnZwG54kOpT4q9CVWbf4zvdU223lrE5w/uIzXZcObQiAAAA")
},
"updateobj" : {
    "$set" : {
        "b" : BinData(0,"D8u1Sk/fDES4IkipZzme7j2qJ4oWjlT3hvLiAilcIhU="),
        "s" : true
    }
}
_

これは典型的なアップデートであり、私の要件は毎秒3000のレートで挿入されます。

残念ながら、これらの処理には2倍の時間がかかります。たとえば、最後の更新は1723文書で、1061ミリ秒かかりました。

コレクションには_idのインデックスのみがあり、他のインデックスはありません。コレクションの平均ドキュメントサイズは244バイトで、上限はありません。

サーバーには64 GBのメモリ、12スレッドがあります。インサートのパフォーマンスは、コレクションサイズが小さく、たとえば約5,000万の場合に優れていますが、約8,000万を超えると実際に低下し始めます。

セット全体が記憶に残っていないためでしょうか?データベースはRAID0 SSDによってサポートされているので、IOパフォーマンスがボトルネックになることはありませんし、それが最初からこれを示しているはずだったのですか?

MongoDBは、使用されている一部のアプリケーションと比較して、わずかな要件を満たすことができると確信しているため、いくつかのガイダンスをいただければ幸いです。

どちらにしても、現在の挿入率は十分ではありません。

更新:クエリのみの説明()です...

_"queryPlanner" : {
    "plannerVersion" : 1,
    "namespace" : "Collection",
    "indexFilterSet" : false,
    "parsedQuery" : {
        "_id" : {
            "$eq" : { "$binary" : "SxHHwTMEaOmSc9dD4ng/7ILty0Zu0qX38V81osVqWkAAAAAA", "$type" : "00" }
        }
    },
    "winningPlan" : {
        "stage" : "IDHACK"
    },
    "rejectedPlans" : []
},
"executionStats" : {
    "executionSuccess" : true,
    "nReturned" : 1,
    "executionTimeMillis" : 1,
    "totalKeysExamined" : 1,
    "totalDocsExamined" : 1,
    "executionStages" : {
        "stage" : "IDHACK",
        "nReturned" : 1,
        "executionTimeMillisEstimate" : 0,
        "works" : 2,
        "advanced" : 1,
        "needTime" : 0,
        "needFetch" : 0,
        "saveState" : 0,
        "restoreState" : 0,
        "isEOF" : 1,
        "invalidates" : 0,
        "keysExamined" : 1,
        "docsExamined" : 1
    },
    "allPlansExecution" : []
},
_

クエリ自体は非常に高速で、更新操作には約25ミリ秒かかり、BulkWriterを使用してMongoにプッシュされます:await m_Collection.BulkWriteAsync(updates);

23
James

書き込み懸念レベル を変更してみてください。明らかに、これにはリスクがあり、書き込みエラーをキャッチすることはできませんが、少なくともネットワークエラーをキャプチャすることはできます。 MongoDBは一括挿入操作を groups of 10 にグループ化するため、これはプロセスを高速化する必要があります

[〜#〜] w [〜#〜]デフォルトでは1です:

enter image description here

0に変更すると、次のようになります。

enter image description here

要素の順序を気にする必要がない場合は、順序付けされていない一括操作を呼び出すと速度が向上します

await m_Collection.BulkWriteAsync(updates, new BulkWriteOptions() { IsOrdered = false });

順序付けされていない操作リストを使用すると、MongoDBはリスト内の書き込み操作を任意の順序で並行して実行できます。 リンク

14
D.Rosado

「データベースには実質的な読み取り率がないため、シャーディングは問題を改善しませんが、おそらく私は間違っています。」

更新には読み取りが含まれます。別名、その見捨てられた_idを見つける-おそらく役立つかもしれないが、役に立つとはいえ、シャーディングが役立つかもしれない

1
Gabe Rainbow

ここにマークされた答えは良いです。 InsertManyの代わりにBulkWriteAsyncを使用する他の人がIsOrdered = falseをより早く利用できるように、コードを追加したい

    m_Collection.InsertMany(listOfDocument, new InsertManyOptions() { IsOrdered = false });
0