35

私は NoSQL の世界に不慣れで、MS Sql Server データベースを MongoDB に置き換えることを考えています。私のアプリケーション (.Net C# で記述) は IP カメラとやり取りし、カメラからの各画像のメタ データを MS SQL データベースに記録します。平均して、カメラごとに 1 日あたり約 86400 レコードを挿入しています。現在のデータベース スキーマでは、Camera_1_Images、Camera_2_Images ... Camera_N_Images など、個別のカメラ画像用に個別のテーブルを作成しました。単一の画像レコードは、単純なメタデータ情報で構成されます。AutoId、FilePath、CreationDate など。これにさらに詳細を追加するために、私のアプリケーションはカメラごとに個別のプロセス (.exe) を開始し、各プロセスはデータベースの相対テーブルに毎秒 1 レコードを挿入します。

次の懸念事項について、(MongoDB) の専門家からの提案が必要です。

  1. MongoDB がそのようなデータを保持するのに適しているかどうかを判断するには、最終的には時間範囲に対してクエリを実行します (指定された時間の間に特定のカメラのすべての画像を取得するなど)。私の場合のドキュメントベースのスキーマ設計に関する提案はありますか?

  2. サーバーのスペック (CPU、RAM、ディスク) を教えてください。なにか提案を?

  3. このシナリオではシャーディング/レプリケーションを検討する必要がありますか (レプリカ セットを同期するための書き込みのパフォーマンスを考慮しながら)?

  4. 1 つのデータベースがすべてのカメラの当日の画像を保持し、2 つ目のデータベースが前日の画像のアーカイブに使用されるように、同じマシンで複数のデータベースを使用する利点はありますか? 別々のデータベースで読み取りと書き込みを分割することに関して、これについて考えています。すべての読み取り要求が 2 番目のデータベースによって処理され、最初のデータベースに書き込まれる可能性があるためです。利益になるかどうか?はいの場合、両方のデータベースが常に同期されるようにするためのアイデア。

他の提案は大歓迎です。

4

3 に答える 3

30

私自身、NoSQL データベースの初心者です。したがって、私は潜在的な反対票を犠牲にしてこれに答えていますが、それは私にとって素晴らしい学習経験になるでしょう.

質問に答えるために最善を尽くす前に、MS SQL Server がうまく機能しているのであれば、それを使い続けることをお勧めします。ドキュメント指向のデータベースとしてそれについて学んだという事実を除いて、MongoDB を使用する正当な理由について言及していません。さらに、各カメラでキャプチャしているメタデータのセットがほぼ同じであることがわかります。つまり、スキーマは動的です。

  • MongoDB がそのようなデータを保持するのに適しているかどうかを判断するには、最終的には時間範囲に対してクエリを実行します (指定された時間の間に特定のカメラのすべての画像を取得するなど)。私の場合のドキュメントベースのスキーマ設計に関する提案はありますか?

ドキュメント指向のデータベースであるMongoDBは、集約でのクエリに適しています(ドキュメントと呼びます)。すでに各カメラのデータを独自のテーブルに格納しているため、MongoDB ではカメラごとに個別のコレクションが作成されます。日付範囲クエリを実行する方法は次のとおりです。

  • サーバーのスペック (CPU、RAM、ディスク) を教えてください。なにか提案を?

すべての NoSQL データベースは、コモディティ ハードウェア上でスケールアウトできるように構築されています。しかし、ご質問のとおり、スケールアップによるパフォーマンスの向上を考えているかもしれません。妥当なマシンから始めて、負荷が増加するにつれてサーバーを追加し続けることができます (スケールアウト)。ハイエンド サーバーを計画して購入する必要はありません。

  • このシナリオではシャーディング/レプリケーションを検討する必要がありますか (レプリカ セットを同期するための書き込みのパフォーマンスを考慮しながら)?

MongoDBは、1 回の書き込みでデータベース全体をロックし (ただし、他の操作では解放します)、書き込みよりも読み取りが多いシステムを対象としています。したがって、これはシステムの状態によって異なります。シャーディングには複数の方法があり、ドメイン固有にする必要があります。一般的な回答はできません。ただし、地理、ブランチなどによるシャーディングなど、いくつかの例を挙げることができます。

また、CAP定理のわかりやすい英語の紹介もお読みください

シャーディングに関するコメントへの回答で更新

彼らのドキュメントによると、次の場合はシャード クラスターの展開を検討する必要があります。

  • データ セットが、システム内の単一ノードのストレージ容量に近づいているか、超えています。
  • システムのアクティブなワーキング セットのサイズが、まもなくシステムの RAM の最大容量を超えます。
  • システムに大量の書き込みアクティビティがあり、単一の MongoDB インスタンスでは要求を満たすのに十分な速度でデータを書き込むことができず、他のすべてのアプローチでは競合が減少していません。

最後のポイントに基づいて、はい。自動シャーディング機能は、書き込みをスケーリングするために構築されています。その場合、データベースごとではなく、シャードごとに書き込みロックがあります。しかし、私のは理論的な答えです。10gen.com グループから相談を受けることをお勧めします。

于 2012-11-02T08:06:00.097 に答える
4

MongoDB がそのようなデータを保持するのに適しているかどうかを判断するには、最終的には時間範囲に対してクエリを実行します (指定された時間の間に特定のカメラのすべての画像を取得するなど)。

この質問は主観的すぎて私には答えられません。多数の SQL ソリューション (皮肉なことに MS SQL ではありません) の個人的な経験から、正しく行われれば、どちらも同じように優れていると言えます。

また:

サーバーのスペック (CPU、RAM、ディスク) を教えてください。なにか提案を?

あなただけが知っているあまりにも多くの変数に依存しますが、コモディティ ハードウェアの小さなクラスターは非常にうまく機能します。この質問に対して事実に基づいた回答をすることはできません。それはあなたのテストにかかっています。

スキーマに関しては、次の構造のドキュメントを使用します。

{
    _id: {},
    camera_name: "my awesome camera",
    images: [
        { 
            url: "http://I_like_S3_here.amazons3.com/my_image.png" ,
            // All your other fields per image
        }
    ]
}

これは、クエリに応じて少し面倒になる可能性があるため、深く埋め込まない限り、維持および更新が非常に簡単なはずです。

それだけでなく、必要なすべてのデータが 1 つのドキュメントに含まれているため、これはシャーディングに適しているはずです。シャードする_id場合は、おそらくここで完璧なセットアップを取得できます。

このシナリオではシャーディング/レプリケーションを検討する必要がありますか (レプリカ セットを同期するための書き込みのパフォーマンスを考慮しながら)?

おそらく、多くの人は、実際にはデータベースの設計方法をより賢くする必要があるだけなのに、シャーディングが必要だと思い込んでいます。MongoDB は非常に自由な形式であるため、間違った方法がたくさんありますが、そうは言っても、正しい方法もたくさんあります。私は個人的にシャーディングを念頭に置いています。レプリケーションも非常に便利です。

1 つのデータベースがすべてのカメラの当日の画像を保持し、2 つ目のデータベースが前日の画像のアーカイブに使用されるように、同じマシンで複数のデータベースを使用する利点はありますか?

MongoDB の書き込みロックは (現在) DB レベルにありますが、私はこう言います: いいえ。適切なドキュメント構造と適切なシャーディング/レプリケーション (必要な場合) は、単一のドキュメント ベースのコレクションでこれを処理できるはずです。 DB。それだけでなく、クラスター内の特定のマシン間で同時実行状況を作成するために、クラスター内の書き込みと読み取りを特定のサーバーに送信できます。DB の分離よりも、MongoDB の同時実行機能を正しく使用することをお勧めします。

編集

質問をもう一度読んだ後、1​​日に各カメラに80k以上の画像を挿入しているという私の解決策を省略しました。そのため、埋め込みオプションの代わりに、実際には、呼び出されたコレクション内の画像ごとに行を作成し、images次にcameraコレクションを作成して、SQL で行うように 2 つをクエリします。

コレクションのシャーディングもimages同様に簡単camera_idです。

また、サーバーで作業セットを考慮してください。

于 2012-11-02T08:33:49.493 に答える
3

MongoDB がそのようなデータを保持するのに適しているかどうかを判断するには、最終的には時間範囲に対してクエリを実行します (指定された時間の間に特定のカメラのすべての画像を取得するなど)。私の場合のドキュメントベースのスキーマ設計に関する提案はありますか?

MongoDB はこれを行うことができます。パフォーマンスを向上させるために、時間フィールドにインデックスを設定できます。

サーバーのスペック (CPU、RAM、ディスク) を教えてください。なにか提案を?

RAMとディスクが重要だと思います。

  • したくない場合は、すべてのデータを保存できるように、より大きなサイズのディスクを検討する必要がありますshardingscale out
  • ホット データは RAM に収まる必要があります。そうでない場合は、MongoDB のパフォーマンスは主に RAM に依存するため、より大きな RAM を検討する必要があります。

このシナリオではシャーディング/レプリケーションを検討する必要がありますか (レプリカ セットを同期するための書き込みのパフォーマンスを考慮しながら)?

合計 1000 台のカメラで 1 秒あたり 1000 回の挿入でも、MongoDB にとっては簡単なはずです。挿入のパフォーマンスが気になる場合は、シャーディングを行う必要はないと思います (ただし、データ サイズが大きすぎて複数のマシンに分割する必要がある場合を除きます)。

もう 1 つの問題は、アプリケーションの読み取り頻度です。非常に高い場合は、ここでシャーディングまたはレプリケーションを検討できます。また、クエリが時間範囲内の 1 台のカメラに対してのみの場合は、(timestamp + camera_id) をシャーディング キーとして使用できます。

1 つのデータベースがすべてのカメラの当日の画像を保持し、2 つ目のデータベースが前日の画像のアーカイブに使用されるように、同じマシンで複数のデータベースを使用する利点はありますか?

archiveテーブルを 2 つのコレクション (と)に分けることができますcurrentarchive日付のみをクエリする場合は、インデックスのみを設定しますarchive。インデックス作成のオーバーヘッドがなければ、currentコレクションは挿入の恩恵を受けるはずです。

currentまた、データをにダンプする毎日のプログラムを作成できますarchive

于 2012-11-02T14:33:53.893 に答える