sql >> データベース >  >> NoSQL >> MongoDB

MongoDBで数十億の小さなドキュメントを高速検索するための戦略

    いくつかの戦略が思い浮かびます:

    1)「ホット」ドキュメントには個別のコレクション/データベースを使用します。

    ホットセットに含まれるドキュメントがわかっている場合は、はい、それらを別のコレクションに移動すると役立ちます。これにより、ホットドキュメントが同じエクステント/ページに共存することが保証されます。また、これらのドキュメントのインデックスが完全にメモリ内にある可能性が高くなります。これは、サイズが小さく、(完全に?)より頻繁に使用されているためです。

    ホットドキュメントが他のドキュメントとランダムに混在している場合、別のドキュメントが最近インデックスブロックをロードまたはアクセスした可能性が低いため、ドキュメントをロードするときにBツリーインデックスのリーフ要素の多くで障害が発生する可能性があります。

    2)インデックス付けされたを短くします 。

    インデックス値が短いほど、単一のBツリーブロックに収まる値が多くなります。 (注:キーはインデックスに含まれていません。)単一のバケット内のエントリが多いほど、インデックスに必要なバケットと合計メモリが少なくなります。これは、ブロックがメモリにとどまる可能性が高く、寿命が長いことを意味します。あなたの例では、20-> 8文字の削減は、50%の節約よりも優れています。これらの8バイトをlongに変換できる場合、longには長さのプレフィックス(4バイト)と末尾のnull(合計5バイト)がないため、もう少し節約できます。

    3)キー名を短くします。

    フィールド名が短いほど、各ドキュメントに必要なスペースが少なくなります。これには、読みやすさが低下するという不幸な副作用があります。

    4)シャード

    これは、メモリと最終的なディスク帯域幅を使い果たすコーパス全体にわたる読み取りに直面してパフォーマンスを維持する唯一の方法です。シャーディングを行う場合でも、「ホット」コレクションをシャーディングする必要があります。

    5)ディスク上の先読みを小さい値に調整します。

    「非ホット」読み取りはディスクからランダムなドキュメントをロードしているため、実際には、そのドキュメントとその周囲のドキュメントをできるだけ少なくして、メモリに読み取り/フォールトするだけです。ほとんどのシステムは、ユーザーがファイルの一部から読み取ると、大量のデータブロックを先読みしようとします。これは私たちが望んでいることとは正反対です。

    システムに多くの障害が発生しているのに、mongodプロセスの常駐メモリがシステムの使用可能なメモリに近づかない場合は、OSが役に立たないデータを読み取った場合の影響が見られる可能性があります。

    6)キーには単調に増加する値を使用してみてください。

    これにより、(ObjectIdベースのインデックスの)最適化がトリガーされ、インデックスブロックが分割されると、50/50ではなく90/10で分割されます。その結果、インデックス内のほとんどのブロックが容量に近くなり、必要なブロックが少なくなります。

    事後に「ホット」な50,000のドキュメントしかわからない場合は、それらをインデックス順に別のコレクションに追加すると、この最適化もトリガーされます。

    ロブ。




    1. Redis/Jedisは単一障害点および自動フェイルオーバーではありません

    2. Neo4jとMongoDBを使用したSpringデータ

    3. マングースのオブジェクトIDから作成日を取得する方法は?

    4. findOneAndUpdateは関数ではありません