web-dev-qa-db-ja.com

ファイルストレージとしてのMongoDB

私は大きなファイル用のスケーラブルなストレージを作成するための最良のソリューションを見つけようとしています。ファイルサイズは1〜2メガバイトから最大500〜600ギガバイトまでさまざまです。

HadoopとHDFSについての情報をいくつか見つけましたが、Map/Reduceジョブや他の多くの機能は必要ないため、少し複雑に見えます。今、MongoDBを使用することを考えています。これはファイルストレージソリューションとしてのGridFSです。

そして今、質問:

  1. 同時にいくつかのファイルを書き込もうとすると、gridfsはどうなりますか。読み取り/書き込み操作にロックはありますか? (ファイルストレージとしてのみ使用します)
  2. GridfsからのファイルはRAMにキャッシュされ、読み書きパフォーマンスにどのように影響しますか?
  3. 私の問題をより効率的に解決できる他の解決策がありますか?

ありがとう。

21
cmd

ここではMongoDBについてのみ答えることができますが、HDFSやその他のそのようなテクノロジーについてよく知っているふりはしません。

GridFsの実装は、ドライバー自体の中の完全にクライアント側です。これは、MongoDB自体の中でファイルサービスのコンテキストの特別な読み込みや理解がないことを意味し、事実上、MongoDB自体はそれらがファイルであることすら理解していません( http://docs.mongodb.org/manual/applications/gridfs/ )。

これは、filesまたはchunksコレクションの任意の部分を照会すると、他のクエリと同じプロセスになり、必要なデータが作業セットにロードされることを意味します(- http://en.wikipedia.org/wiki/Working_set )これは、最適なパフォーマンスを維持するために特定の期間内にMongoDBが必要とする一連のデータ(またはその時点で読み込まれたすべてのデータ)を表します。これをRAM(技術的にはOSが行う)にページングすることで行います。

考慮すべきもう1つの点は、これが実装されたドライバーであることです。これは、仕様が変化する可能性があることを意味しますが、そうではないと思います。すべてのドライバを使用すると、ファイルメタデータのみを格納するfilesコレクションからドキュメントのセットを照会でき、後で単一のクエリでchunksコレクションからファイル自体を提供できます。

ただし、それは重要なことではありません。データを含め、ファイル自体を提供する必要があります。これは、filesコレクションとそれに続くchunksコレクションを作業セットにロードすることを意味します。

それを念頭に置いて、私たちはすでに最初のひっかかりを見つけました:

GridfsからのファイルはRAMにキャッシュされ、読み書きパフォーマンスにどのように影響しますか?

小さなファイルの読み取りパフォーマンスは、RAMから直接、素晴らしいものになる可能性があります。書き込みも同じくらい良いでしょう。

大きなファイルの場合はそうではありません。ほとんどのコンピューターには、600 GBのRAMがありません。実際、非常に普通のことですが、単一のmongodインスタンスに単一ファイルの600 GBパーティションを収容することは可能です。このファイルは、提供されるために作業セットに収まる必要があるため問題が発生しますが、RAMよりもかなり大きいため、この時点でページスラッシング( http://en.wikipedia。 org/wiki/Thrashing_%28computer_science%29 )これにより、サーバーはファイルをロードしようとして24時間年中無休のページフォールトになります。

これを回避する唯一の方法は、単一のファイルを多数のシャードに配置し始めることです:\

注:考慮すべきもう1つの点は、chunks "チャンク"のデフォルトの平均サイズが256KBであるため、600GBファイルのドキュメントが大量にあることです。この設定は、ほとんどのドライバーで操作可能です。

同時にいくつかのファイルを書き込もうとすると、gridfsはどうなりますか。読み取り/書き込み操作にロックはありますか? (ファイルストレージとしてのみ使用します)

GridFSは、データベースレベル(2.2以降)またはグローバルレベル(2.2以前)で、他のコレクションと同じロック、読み取りおよび書き込みロックの両方を使用するだけの仕様です。 2つは互いに干渉します。つまり、書き込み中のドキュメントの一貫した読み取りをどのように保証できますか。

とはいえ、競合の可能性は、シナリオの詳細、トラフィック、同時書き込み/読み取りの数、および他の多くのことについて私たちが知らないことに基づいています。

私の問題をより効率的に解決できる他の解決策がありますか?

私は個人的に、S3(@mluggyが述べたように)を冗長性の少ない形式で使用すると、MongoDB内のファイルに関するメタデータのほんの一部を保存するのに最も適していることを発見しました。あなたのための他のもの。

うまくいけば、それが助けになることを願っています。

編集:私が誤って言ったこととは異なり、MongoDBにはコレクションレベルのロックはありません。それはデータベースレベルのロックです。

18
Sammaye

最初の2つに答えることから始めます。

  1. はい、GridFSへの書き込み時に書き込みロックがあります。読み取りのロックはありません。
  2. クエリを実行してもファイルはメモリにキャッシュされませんが、メタデータはキャッシュされます。

GridFSは、問題の最善の解決策ではない場合があります。書き込みロックは、このような状況、特に巨大なファイルを扱う場合に苦痛になることがあります。この問題を解決できるデータベースは他にもあります。 HDFSは良い選択ですが、あなたが言うように、それは非常に複雑です。 RiakやAmazonのS3などのストレージメカニズムを検討することをお勧めします。ファイルを保存することを重視しているため、大きな欠点はありません。 S3とRiakはどちらも優れた管理機能を備えており、巨大なファイルを処理できます。最後に私が知っていたRiakでは、100 MBを超えるファイルを保存するためにファイルチャンキングを行う必要がありました。それにもかかわらず、一般的には、巨大なファイルサイズに対してある程度のチャンキングを行うことがベストプラクティスです。ファイルをDBに転送するときに発生する可能性のある悪いことがたくさんあります。ネットワークタイムアウトからバッファオーバーフローなどです。

メタデータをMongoDBに保存し、実際のファイルをAmazon S3に書き込むことを検討しましたか?どちらにも優れたドライバーがあり、後者は非常に冗長なクラウド/ cdn対応のファイルストレージです。試してみます。

4
mluggy