2

ログ管理システム用の最初の MongoDB データベース スキーマを設計しています。ログ ファイルから mongoDB に情報を保存したいのですが、大きなドキュメント (埋め込みと参照) にどのスキーマを使用すればよいか判断できません。

注: プロジェクトには多くのソースがあり、ソースには多くのログがあります (場合によっては 1 000 000 を超えるログ)

  {    
      "_id" : ObjectId("5141e051e2f56cbb680b77f9"),   
      "name" : "projectName",
      "source" : [{
          "name" : "sourceName",
          "log" : [{
              "time" : ISODate("2012-07-20T13:15:37Z"),
              "host" : "127.0.0.1",
              "status" : 200.0,
              "level" : "INFO",
              "message" : "test"
            }, {
              "time" : ISODate("2012-07-20T13:15:37Z"),
              "host" : "127.0.0.1",
              "status" : 200.0,
              "level" : "ERROR",
              "message" : "test"
            }]
        }]
    }

私の焦点は、データベースからデータを読み取るときのパフォーマンス(書き込みではありません)、たとえば、フィルタリング、検索、ページネーションなどです。ユーザーは、日付、ステータスなどでソースログをフィルタリングできます(したがって、ユーザーがデータを検索またはフィルタリングするときの読み取りパフォーマンスに焦点を当てたいと思います)

MongoDB には 16M バイトのドキュメント サイズの制限があることを知っているので、1 つのソースに対して 1 000 000 のログがどのように機能するか心配です (1 つのプロジェクトに対して多くのソースがあり、ソースには多くのログがある可能性があるため)。大規模なドキュメントを扱う場合、優れた読み取りパフォーマンスを実現したい場合、より良い解決策は何ですか?埋め込みスキーマまたは参照スキーマを使用する必要がありますか? ありがとう

4

2 に答える 2

3

あなたの質問への答えはどちらでもありません。参照を埋め込んだり使用したりする代わりに、スキーマをログ エントリごとに 1 つのドキュメントにフラット化して、16 MB のドキュメント制限に収まる範囲を超えてスケ​​ーリングし、MongoDB のクエリ機能のフルパワーとパフォーマンスにアクセスできるようにする必要があります。

したがって、配列フィールドを取り除き、次のようなアプローチを使用してすべてをトップレベルのフィールドに移動します。

{    
    "_id" : ObjectId("5141e051e2f56cbb680b77f9"),   
    "name" : "projectName",
    "sourcename" : "sourceName",
    "time" : ISODate("2012-07-20T13:15:37Z"),
    "host" : "127.0.0.1",
    "status" : 200.0,
    "level" : "INFO",
    "message" : "test"
  }, {
    "_id" : ObjectId("5141e051e2f56cbb680b77fa"),   
    "name" : "projectName",
    "sourcename" : "sourceName",
    "time" : ISODate("2012-07-20T13:15:37Z"),
    "host" : "127.0.0.1",
    "status" : 200.0,
    "level" : "ERROR",
    "message" : "test"
}
于 2013-03-14T15:34:26.750 に答える
1

プロジェクトとソース エンティティに名前以外の属性 (キー) がなく、ログを長期間保存しない場合は、ログごとに 1 つのログを持つ上限付きコレクションを使用できます。資料:

{_id: ObjectId("5141e051e2f56cbb680b77f9"), p: "project_name", s: "source_name", "time" : ISODate("2012-07-20T13:15:37Z"), "host" : "127.0.0.1", "status" : 200.0, "level" : "INFO", "message" : "test"}

これも参照してください: http://docs.mongodb.org/manual/use-cases/storing-log-data/

キャップされたコレクションは自然な順序を維持します。したがって、自然な順序でログを返すためにタイムスタンプのインデックスは必要ありません。あなたの場合、特定のソース/プロジェクトからすべてのログを取得したい場合があります。インデックス{p:1,s:1}を作成して、このクエリを高速化できます。

ただし、パフォーマンスを確認するために「ベンチマーク」を行うことをお勧めします。上記の上限付きコレクションのアプローチを試してください。また、提案した完全に埋め込まれたスキーマを使用してドキュメントをバケット化してみてください。この手法は、古典的なブログのコメントの問題で使用されます。したがって、各ソースの非常に多くのログを単一のドキュメント内に保存するだけで、カスタム定義のサイズを超えるたびに新しいドキュメントにオーバーフローします。

于 2013-03-14T16:12:48.370 に答える