web-dev-qa-db-ja.com

サーバー上のCPU集中タスクをバックグラウンドで効率的に処理する方法

Railsを使用してオーディオ処理Webアプリを作成しました。ユーザーが曲をウェブサイトにアップロードします。次に、曲は個々の要素に分解され、変更されて再結合されます。

Railsコントローラから呼び出されているオープンソースのコマンドラインツールを使用しています。

私の問題:処理に約2〜3分かかり、大量のメモリを消費します。ブラウザは2〜3分間、ロード段階にあります。そして、これは、1人のユーザーからの1つのリクエストに対するものです。 Amazon ec2インスタンスt1.largeを使用していますが、それだけでは不十分です。

バックグラウンド処理を使用する予定ですが、複数のリクエストが同時に機能することを望みません。

最初のリクエストには3分かかります。 3 + 3分の2回目のリクエスト。 3 + 3 + 3分かかる3番目の要求。だからウェブサイトはダウンしません。

また、オーディオファイルは約40 MBです。 Amazon s3バケットを使用することは良い考えですか?または、ハードディスクの容量を増やして、オーディオファイルをサーバーに保存しますか?

Amazon s3バケットを使用したくないのは、レイテンシーが増えるため、ec2インスタンスからs3バケットに各ファイルを再度転送したくないためです。

1
musicjackx

Railsにはバックグラウンドタスク処理用の組み込みフレームワークがあるため、長いタスクがコントローラーがクライアントに応答を返すのを妨げることはありません。これはアクティブジョブと呼ばれます。 (参照: https://guides.rubyonrails.org/active_job_basics.html )Active Jobを使用することは、ユーザーのブラウザーを数分間ロードしたままにするよりも優れたオプションです。

バックグラウンド処理が完了したときに、ブラウザを更新する方法がまだ必要な場合があります。これを行う方法はたくさんありますが、おそらく最も簡単な方法は次のとおりです。

  1. 送信されたジョブごとにDBにレコードを挿入します
  2. バックグラウンド処理が完了したら、ジョブレコードに「完了」フラグ(ブール値)を設定します。
  3. ジョブが完了したかどうかをチェックし、完了した場合は、ユーザーに表示する必要のあるデータを返すコントローラーアクションを追加します。
  4. ジョブが完了するまでN秒ごとにサーバーをポーリングするクライアント側JSを追加します

オーディオファイルをローカルに、またはS3に保持する方が、詳細情報なしで「より良い」かどうかを判断することはできません。おそらく、これらのファイルのコピーを永久に保持するのではなく、処理中だけですか?もしそうなら、一度に保持する必要があるかもしれない最大数は何ですか?これは、使用可能なディスク領域に収まり、十分な余裕がありますか? (サーバーの空きディスク領域をゼロに近づけることは悪い考えです。)そうでない場合、より大きなEC2インスタンスのコストはS3を使用するコストとどのように比較されますか?

各ファイルの処理には2〜3分かかるとおっしゃっていました。 S3との間でファイルを転送するのに必要な時間が本当にそれを著しく増加させるのだろうかと思います。とにかく、両方の方法を試すと、違いが出るかどうかが確実にわかります。

3
Alex D