web-dev-qa-db-ja.com

スケーラビリティを容易にするためにEC2でRails 2.3.xアプリをセットアップする

単純なRailsスタックを1台の専用マシンで実行しています。フルキャパシティーに到達しており、スケーリングのセットアップはまったくありません。1台のマシンに1つのアプリしかありません。スケーラビリティの潜在的なスタックを思いついた。私はプロの管理者ではないが、EC2で何をすべきかについていくつかの考えをまとめた。ファイルシステムの共有についてはまだ少し確信が持てない。 。最初に、これが私が扱っているものです。

現在のスタック:

  • レール2.3.11
  • postgresql
  • 乗客+ nginx
  • delayd_job
  • スフィンクス+ thinking_sphinx
  • imagemagick(重い画像処理)
  • ジャクサー(説明します)

私たちのアプリが行うこと:

私たちのアプリは、ImageMagickを使用して多くの画像アップロードと大量の画像処理を行います。また、長いキャンバスから画像への変換についてjaxerと通信します。これはすべて遅れた仕事です。このようなものが特に拡張できることを確認したいと思います。つまり、急成長しているファイルストレージのニーズと、バックグラウンドジョブでの大量の画像処理について話しているのです。

これまでの私の決定:

  • 展開/管理を支援するためにゴム製の宝石を使用する
  • ワーカー(クライアント/サーバー)、複数のキュー、およびsinatra Webインターフェイスの分離を容易にするために、delayed_jobからredis/resqueに移動します
  • app、db、web、redis、resqueなどの役割があり、最初はすべてが単一のec2インスタンスにありますが、すぐにredis/resqueのものを別のインスタンスに分割し、場合によってはそれらの多くを分割します

質問:

主な実際の質問は、すべてのファイルはどうなるのかということです。アプリの役割を複数のインスタンスに分割することにした場合、共有ファイルシステムアクセスを取得するにはどうすればよいですか?

さらに、私のセットアップ全般についての考えを聞くのは素晴らしいことです。

3
Max Chernyak

したがって、そこにあるもののほとんどは、スケーリングするのが非常に簡単です。最初のステップとして、CPU /ディスクIO /メモリ消費の山を軽減するために独自のマシンにPgSQLをインストールします。それ自身の小さな世界にもスフィンクス。確実にresqueに切り替えて、ワーカーの水平方向のスケーリングを簡単に行えるようにします。

しかし、ファイル...はい、ファイルは難しいです。彼らはいつも難しいです。そして、あなたの選択肢は危険なほど薄いです。

一部の人々は、マジックスーパークラスタリング(GFS2/OCFS2)またはGlusterFSのような少し貧弱なオプションのいずれかのクラスター化されたファイルシステムルートを推奨します。私はGFSを使用して多くのシステム(1000以上)を実行しましたが、決して実行しませんでしたeverもう一度実行します。 (実際には、EC2のネットワーク上で実行されない場合もあります)。 GFS2/OCFS2は可動部分の混乱であり、文書化が不十分で、複雑すぎて、ダウンタイムの煩わしさを与えるだけの混乱する障害モードになりがちです。また、特に書き込みが多い環境では、気にしないほどのパフォーマンスはありません。クラスター全体がダウンし、10〜30分の教祖レベルの作業で再び稼働するようになります。それを避けてください、そうすればあなたの人生はずっと楽になります。 GlusterFSを実行したことはありませんが、特に感銘を受けたことがないためです。あなたがそれでできることは何でも、とにかくそれをするためのより良い方法が通常あります。

私の意見では、より良いオプションは由緒あるNFSサーバーです。大きな(またはそれほど大きくない)EBSボリュームとNFSデーモンが実行されている1台のマシンで、全員がそれをマウントします。落とし穴があります(本当に POSIXファイルシステムではないので、そのように扱わないでください)が、99%のユースケースで単純な「そこに修正しました」操作の場合は悪くありません。少なくとも、より良いソリューションに取り組んでいる間、それは一時的なものになる可能性があります。

アプリケーションに関する知識を使用して、ストレージを階層化します。これは私が最近採用したアプローチ(Githubのスケーリング)であり、見事に機能しています。基本的に、ファイルストレージをファイルシステムとして扱うのではなく、サービスのように扱います-ファイルストレージにインテリジェントなAPIを提供します-アプリケーションの一部を使用して、あなたが行うことを実行します必要 。あなたの場合、事前に割り当てられたID(たとえば、DB内の「images」テーブルのPK)に画像を保存および取得できる必要があるだけかもしれません。 POSIXファイルシステム全体は必要ありません。いくつかの超最適化されたHTTPメソッドが必要です(POSTは動的に処理する必要がありますが、本当に賢い場合はGETを実行できます静的ファイルとしてディスクから直接)。地獄、あなたはおそらくそれらの画像を顧客に直接提供しているので、仲介者を切り取って、あなたがそこにいる間、そのサーバーをあなたの公的にアクセス可能な資産サーバーにします。

その場合、ワークフローは次のようになります。

  • フロントエンドサーバーがイメージを取得します
    1. ファイルサーバーにPOSTします
    2. 画像を処理するジョブを追加します
    3. (または、ファイルサーバーへのPOSTにより、後処理ジョブの必要性が認識され、ジョブがすべて自動的に作成されます)
  • 労働者は画像処理の仕事を得る
    1. ファイルサーバーから画像を取得します
    2. 画像を処理します
    3. 処理された画像をファイルサーバーにPOSTします
  • ウェブページはウェブページに画像を含める必要があります
    1. 画像サーバーへのURLをHTMLに書き込みます
    2. ウェブブラウザが行き、画像を直接取得します

サーバーに画像を配置するために、必ずしもHTTP POSTを使用する必要はありません。たとえば、Githubは、Git-over-SSHを使用してファイルサーバーと通信します。ただし、重要なのは、作業を行う必要がある場所をより深く検討し、不足しているリソース(ネットワークIO NFSサーバー要求の場合))の不要な使用を避け、代わりにアプリケーションで機能する、より制約のある一連の使用オプション(「ファイル全体をアトミックにのみ要求できます!」)。

最後に、スケーラビリティの要素を考慮する必要があります。ただし、インテリジェントトランスポートを使用している場合は、それは簡単です。ファイルサーバーと通信する各場所で、通信する必要のあるファイルサーバーを決定するために必要な(少量の)ロジックを追加すると、基本的に無限のスケーラビリティが得られます。 。あなたの状況では、最初のファイルサーバーが、たとえば750,000枚の画像でいっぱいになることに気付くかもしれません。したがって、ルールは「ホスト名fs#{image_id / 750_000}でファイルサーバーと通信する」です。これは、どこでもエンコードするのは難しくありません。

私はいつも仕事のこの部分を楽しんでいました...

9
womble