web-dev-qa-db-ja.com

Railsアプリで大きなファイルのアップロードを処理する最良の方法は何ですか?

Railsアプリケーション、2-5Gbファイルでの大きなファイルのアップロードを処理するさまざまなアプローチを理解することに興味があります。

このサイズのファイルを転送するには、より小さな部分に分割する必要があることを理解し、いくつかの研究を行ってきましたが、これがこれまでの結果です。

  • サーバー側の設定では、大きなPOST要求と、おそらく64ビットマシンで 4Gbを超えるもの を処理する必要があります。
  • AWSは multipart upload。 をサポートしています
  • HTML5 FileSystemAPI には、ファイルをチャンクでアップロードする永続的なアップローダーがあります。
  • Bitorrent のライブラリですが、これには理想的ではない送信クライアントが必要です

FTPのようにこれらすべての方法を再開できますか。FTPを使いたくないのは、これが可能であればWebアプリに残しておくためです。 CarrierwaveとPaperclipを使用しましたが、5Gbファイルのアップロードには時間がかかる可能性があるため、再開できるものを探しています!

私がリストしたこれらのアプローチのうち、うまくいったものを理解したいと思います。また、私が見逃しているかもしれない他のアプローチがあれば?可能な場合、プラグインはJava AppletsまたはFlashを使用しません。別の懸念は、これらのソリューションがアップロード中にファイルをメモリに保持することです。

39
cih

上記で説明したテクニックのいくつかを使用して、いくつかのサイトでこの問題を処理しました。幸いなことに、大量のアップロードを許可するのは実際にはかなり現実的です。

これの多くは、ファイルをアップロードした後、実際にファイルをどのように処理するかによって異なります...ファイルに対してより多くの作業を行うほど、サーバーに近づける必要があります。アップロードですぐに処理する必要がある場合は、おそらく純粋なRailsソリューションを実行する必要があります。処理を実行する必要がない場合、またはタイムクリティカルでない場合は、 「ハイブリッド」ソリューションを検討し始めることができます...

信じられないかもしれませんが、実際には mod_porter を使用するだけでかなりの幸運が得られました。 Mod_porterは、Apacheに、アプリが通常行う作業の多くを実行させます。アップロード中にスレッドとメモリを束ねないようにします。処理を簡単にするために、アプリのローカルファイルになります。アップロードされたファイルの処理方法(ストリームを考える)に注意を払えば、従来はかなり高価な操作であったとしても、プロセス全体でメモリをほとんど使用しないようにできます。このアプローチでは、アプリを実際にセットアップする必要はほとんどなく、コードを実際に変更する必要はありませんが、特定の環境(Apacheサーバー)とそれを構成する機能が必要です。

また、 jQuery-File-Upload を使用して幸運にも恵まれました。これは、チャンクアップロードや再開可能なアップロードなどの優れた機能をサポートします。 mod_porterのようなものがなければ、これはまだアップロード中に実行のスレッド全体を拘束する可能性がありますが、適切に行われた場合、メモリにまともなはずです。これにより、ファイルが「近く」になり、その結果、処理が容易になります。この方法では、実装するためにビューレイヤーを調整する必要があり、すべてのブラウザーで機能するわけではありません。

FTPとbittorrentを可能なオプションとして言及しました。ファイルをサーバーにかなり近づけることができるので、これらはあなたが思うほど悪いオプションではありません。 (指摘したように)アップロードマシンに存在する場合と存在しない場合がある追加のクライアントが必要なため、これらは相互に排他的でもありません。これが機能する方法は、基本的に、アプリが表示できる場所をダンプするエリアを設定することです。次に、処理を行う必要がある場合は、cronジョブ(またはその他)を実行して、アップロードの場所を監視し、サーバーの処理方法をトリガーします。これは、上記のメソッドが提供できる即時の応答を取得するものではありませんが、非常に近くなるように間隔を小さく設定することができます。この方法の唯一の本当の利点は、使用されているプロトコルが大きなファイルの転送により適していることです。追加のクライアント要件と断片化されたプロセスは、通常、それによるメリットを上回ります。

処理がまったく必要ない場合は、S3に直接アクセスすることをお勧めします。このソリューションは、静的アセットとしてサーバー以外のファイルを使用して実際に何かをする必要がある場合に数秒かかります。

RailsアプリでHTML5 FileSystemAPIを使用した経験がないため、その点について話すことはできませんが、サポートできるクライアントが大幅に制限されるようです。

残念なことに、真の特効薬はありません。これらのオプションはすべて、達成しようとしていることのコンテキストで環境と比較検討する必要があります。たとえば、Webサーバーを構成したり、ローカルファイルシステムに永続的に書き込むことができない場合があります。 jQuery-File-Uploadは、アプリケーションの変更のみを必要とするため、ほとんどの環境でおそらく最善の策だと思います。したがって、実装を別の環境に最も簡単に移動できます。

34
Brad Werth

このプロジェクトは、大きなファイルの再開可能なアップロードをサポートするHTTPを介した新しいプロトコルです。独自のサーバーを提供することでRailsをバイパスします。

http://tus.io/

4
Bmxer

http://www.jedi.be/blog/2009/04/10/Rails-and-large-large-file-uploads-looking-at-the-alternatives/ にはいくつかの良い比較がありますRails以外のオプションを含むオプション。

私の場合は役に立ちました

また、別のサイトにアクセスしてください:- http://bclennox.com/extremely-large-file-uploads-with-nginx-passenger-Rails-and-jquery

これがうまくいかない場合はお知らせください

3
Catmandu

ブラッド・ワースが答えを打ち付けたと思う

1つのアプローチはS3に直接アップロードできます(理論的にaws lambdaを使用してアプリに通知できた後に再処理が必要な場合でも...同じ問題を自分で、これについては後で説明します)

http://aws.Amazon.com/articles/1434

carrierwaveを使用する場合

1
equivalent8

Railsサーバーをバイパスし、大きなファイルを(チャンクに分割して)ブラウザから直接 Amazon Simple Storage に投稿します。これを見てください- post JavaScriptでファイルを分割する場合、このセットアップのパフォーマンスが少し気になるので、今週末はこのセットアップをいじくり回したい気がします。

1
eabraham