2013-07-28 13 views
17

私のRoR4 HerokuアプリケーションでPuma(マルチスレッド+マルチコアサーバ)を設定する際に助けが必要です。 その上のHerokuドキュメントは最新ではありません。私はこれに続いて:構成のためのConcurrency and Database Connections、それはクラスタのための構成を言及しないので、私は両方のタイプ(スレッドとマルチコア)を一緒に使用しなければならなかった。HerumaのPumaクラスタ設定

私の現在の構成:

./Procfile

web: bundle exec puma -p $PORT -C config/puma.rb 

./config/puma.rb

environment production 
threads 0,16 

workers 4 
preload_app! 

on_worker_boot do 
    ActiveRecord::Base.connection_pool.disconnect! 

    ActiveSupport.on_load(:active_record) do 
    config = Rails.application.config.database_configuration[Rails.env] 
    config['reaping_frequency'] = ENV['DB_REAP_FREQ'] || 10 # seconds 
    config['pool']    = ENV['DB_POOL'] || 5 
    ActiveRecord::Base.establish_connection 
    end 
end 

質問:

a)クラスタワーカーはフォークされているので、Unicornのようなbefore_fork/after_fork設定が必要ですか?
b)アプリケーションに応じてスレッド数を調整するにはどうすればよいですか?それを削除する理由は何ですか? /それはどのような場合に違いがありますか? 0:16は既に最適化されていませんか?
c)Herokuデータベースでは500件の接続が可能です。スレッド、ワーカー、およびdyno数に応じてDB_POOLにはどのような価値がありますか? - 並行して作業する場合は、dynoごとに1人のスレッドごとに1つのDB接続が必要ですか?

一般的に、並行性とパフォーマンスの設定はどうすればよいですか?

+0

スレッド数を調整する場合私はUnicornのワーカーチューニングのチュートリアルを読んで、「ab」を実行し、パフォーマンス低下(要求が完了するまでに時間がかかる)がなくなるまでワーカー数(あなたの場合はスレッド)を増やすことを提案しました。非常にダイナミックなページを使い、さまざまなリクエスト/同時の割合が最初にどのように作用するかを確認することは良いことです(多くの要求をすると、英雄があなたをDoS疑いで騙してしまうかもしれないことを念頭に置いてください) –

+0

@MichaelSzyndelだから、パフォーマンスをチェックしてから、スレッドを調べてもう一度チェックしますか?正確に何が要求されているかに依存しませんか? – Nikom

+1

私がどこかで読んだところから、Herokuはdynoあたり2つのコア(4つの仮想)を持っています。 dynoごとに1つのプロセスを持つことが最適です。プロセスごとに実行するスレッドの数はあなた次第です。私がabでテストすること。また、521MBのRAMを渡すと、Herokuはアラートを送信し、> 1GBでスワップします(ヒロクのドキュメントで確認してください) –

答えて

26

a) ユニコーンのようなbefore_fork/after_fork設定が必要ですか?クラスタ作業者はフォークされていますか?

通常はありませんが、preload_appを使用しているため、はいです。アプリケーションをプリロードすると、インスタンスが起動して実行され、その後、ワーカーのメモリスペースが壊されます。結果はあなたのイニシャライザは一度だけ実行されます(おそらくDB接続などを割り当てます)。この場合、お客様のon_worker_bootコードが適切です。 preload_appを使用していない場合は、各ワーカーが起動します。この場合、イニシャライザを使用すると、カスタム接続を設定するのに適しています。実際には、preload_appがないと、あなたのon_worker_bootブロックは、その時点でActiveRecordとフレンドがロードされていないためにエラーになります。

b)私のアプリケーションに応じてスレッド数を調整するにはどうすればいいですか? をドロップダウンする理由は何ですか? /どのような場合には の違いがありますか? 0:16は既に最適化されていませんか? Herokuの(と私のテスト)で

あなたはmax < = DB_POOL設定で、あなたのmin/maxスレッドを一致させる最良のです。 minスレッドを使用すると、負荷がかかっていないときにリソースをスピンダウンすることができます。これは通常、サーバー上のリソースを解放するのに最適ですが、Herokuでは必要性は低くなります。そのdynoはすでにWebリクエストを提供することに専念しています。maxスレッド< =環境変数DB_POOLを設定する必要はありませんが、プール内のすべてのデータベース接続を消費する危険性があります。接続は必要ですが接続できないスレッドがあります。古い "ActiveRecord :: ConnectionTimeoutError - 5秒以内にデータベース接続を取得できませんでした。エラー。これはあなたのアプリケーションにもよりますが、max>DB_POOLとうまくいくかもしれません。あなたの接続が熱心に読み込まれていなくても、あなたのDB_POOLは少なくともあなたのminスレッド値と同じでなければなりません(5:5スレッドは5つの接続を開いていません。

c)Herokuデータベースでは500回の接続が可能です。スレッド、ワーカー、およびdynoの数に応じて、DB_POOLの値はどれくらい良い値になるのですか? - は、 が並列処理されている場合、dynoごとに1人の作業者ごとに1つのDB接続が必要ですか?

Production Tierは明確にし、500を可能に:)

ダイノあたりの労働者一人当たりのすべてのスレッドが彼らはすべて同時にデータベースにアクセスしようとしている場合に応じて、接続を消費することができます。通常、接続は一度完了すると再利用されますが、b)で述べたように、スレッドがプールよりも大きい場合は、時間がかかる可能性があります。接続は再利用されますが、これはActiveRecordによって処理されますが、時には理想的ではありません。接続がアイドルになったり、死んでしまうことがあります。そのため、死んだ接続を検出して再利用するために、Reaperをオンにすることをお勧めします。

+0

私は正しく、「労働者2」はプーマのための追加の労働者のプロセスを意味するので、合計で「3」のプロセスがありますか? – gaussblurinc

2

スレッドよりもDB接続が少なくて済みます。別々のプロセスにはそれぞれ独自の接続プールがあるので、DBが20の接続をサポートしていて2つのプロセスを実行したい場合、タイムアウトのリスクなしで実行できるスレッドは10スレッドであり、接続数は10です。

レールコンソールセッション用にいくつかの接続を残す必要があります。また、バックグラウンドワーカーとスレッド化されているかどうかについても気を付けてください。

あなたの労働者が別のプロセス(サイドキック)にいる場合、彼らは自分のプールを持ちます。ワーカーのスレッドがWebプロセス(girl_fridayまたはsucker_punch)から生成された場合、DB_POOLは接続プールを共有するため、Webスレッドの最大数よりも大きくします。

関連する問題