web-dev-qa-db-ja.com

MS SQL Serverの代わりにMongoDBを使用することの長所と短所

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番目のデータベースによって処理され、最初のデータベースに書き込まれるためです。それは恩恵を受けるかどうか? 「はい」の場合、両方のデータベースが常に同期されるようにするためのアイデア。

他の提案は歓迎します。

34
theGeekster

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

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

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

MongoDBはドキュメント指向のデータベースであるため、 within 内のクエリに適しています(ドキュメントと呼びます)。すでに各カメラのデータを独自のテーブルに保存しているので、MongoDBでは、各カメラに個別の collection が作成されます。 方法はこちら 日付範囲クエリを実行します。

  • サーバーの仕様(CPU、RAM、ディスク)はどうすればよいですか?なにか提案を?

すべてのNoSQLデータベースは、汎用ハードウェア上で scale-out に構築されます。しかし、質問したところでは、 scaling-up によってパフォーマンスを改善することを考えているかもしれません。適切なマシンから始めて、負荷が増加しても、サーバーを追加し続けることができます(スケールアウト)。ハイエンドサーバーを計画して購入する必要はありません。

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

MongoDB db全体をロックします 1回の書き込みに対して(ただし、他の操作に対しては収率を上げます)、書き込みよりも読み取りの方が多いシステム向けです。したがって、これはシステムの状態に依存します。シャーディングには複数の方法があり、ドメイン固有である必要があります。一般的な答えは不可能です。ただし、地理や枝などによるシャーディングのような例もあります。

CAP定理の簡単な英語の紹介 も読んでください

sharding に関するコメントへの回答で更新

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

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

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

29

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
        }
    ]
}

これは、クエリを使用することで多少苦痛になる可能性があるため、それ以上深く埋め込みをしない限り、管理と更新が非常に簡単になります。

それだけでなく、これはシャーディングに適しているはずです。なぜなら、_idおそらくここで完璧なセットアップを得ることができます。

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

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

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

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

編集

質問をもう一度読んだ後、ソリューションごとに、1日に各カメラに80k以上の画像を挿入することを省略しました。そのため、埋め込みオプションの代わりに、実際にimagesと呼ばれるコレクションで画像ごとに行を作成し、次にcameraコレクションを作成して、SQLの場合と同様に2つをクエリします。

imagesコレクションのシャーディングは、camera_id

また、サーバーの作業セットを考慮に入れるようにしてください。

4
Sammaye

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

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

サーバーの仕様(CPU、RAM、ディスク)はどうすればよいですか?なにか提案を?

RAMとDiskが重要だと思います。

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

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

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

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

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

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

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

3
Chien-Wei Huang