Apache+Ruby+PostgreSQLによるパフォーマンスチューニングのまとめ
仕事でApache+Ruby+PostgreSQLのパフォーマンスチューニングに携わったので、チューニング項目について備忘録でまとめておきます。
ここに挙げている以外の項目も色々あると思いますので参考程度でお願いします。また不足している項目があればどこかでつぶやいてください。
1.Apacheのチューニング項目
Apacheのチューニングは、httpd.conf(/etc/httpd/conf/httpd.conf)に下記の項目を設定します。
MPM(Multi-Processing Module)はworkerを利用しています。
ThreadsPerChild
ThreadsPerChildは、1プロセスで生成可能なスレッド数を設定します。例えば
ThreadsPerChild 30
と設定すれば1プロセスで30スレッドまで生成されます。
MaxClients
MaxClientsは最大スレッド数を設定します。ThreadsPerChildの超過に応じてMaxClientsになるまで必要分のプロセスが増えていきます。
さきほどの「ThreadsPerChild 30」で
MaxClients 120
と設定すれば、最大4プロセスで動作します。
ServerLimit
ServerLimitは、MaxClientsに設定可能な上限値を設定します。MaxClientsとThreadsPerChildの組み合わせの最大が16プロセス以上必要になる場合にのみ使用します。
keepAlive
keepAliveは同一クライアントに対してコネクション接続を維持するための設定ですが、トラヒックの場合は無効にした方がいいようです。
keepAlive off
keepAliveを利用する場合はタイムアウト値を見直しましょう。デフォルトは15秒です。以下の設定では3秒でタイムアウトします。
keepAliveTimeout 3
2.Phusion Passenger
Phusion Passenger(以下Passenger)は、Ruby on RailsなどををApacheで動かすためのApacheモジュールです。
Passengerのチューニングは、passnger.conf(/etc/httpd/conf.d/passnger.conf)に下記の項目を設定しますが、Apacheのhttpd.confに直接設定することもできます。
両方に設定した場合、httpd.confの設定が優先されました。
PassengerMaxPoolSize
Ruby on Railsのプロセス最大起動数を設定します。多いほど大量のリクエストを同時に処理できますが、その分多くのメモリ必要となります。デフォルトは6です。次の設定では最大15プロセス起動します。
PassengerMaxPoolSize 15
実装に依存するかもしれませんが、topコマンドで確認したところ、Ruby on RailsのプロセスがApacheのスレッド数を超えることはありませんでした。
PassengerUseGlobalQueue
Passengerのグローバルキューの有効/無効を設定します。
Passengerが受け取ったリクエストについて、デフォルトではアプリケーションインスタンス単位にキューが用意されています。
が、処理が長いリクエストの後続のキューのリクエストは、他のインスタンスキューが空いた状態になってもずっと待たされることになります。
PassengerUseGlobalQueueを有効にすれば1つのキューで複数インスタンスに割り当てるので、前述の事象を回避できます。
PassengerUseGlobalQueue on
3.Ruby on Rails
Ruby on Railsのチューニングは、Railsアプリケーションのconfig/database.ymlに下記の項目を設定します。YAML形式なので気をつけてください。
pool
Ruby on Railsで利用するデータベースのコネクションプールを設定します。デフォルトは5ですが、次のように設定すれば10コネクション用意されます。
pool: 10
4.PostgreSQL
PostgreSQLのチューニングは、postgresql.conf(/var/lib/pgsql/data/postgresql.confなど)に下記の項目を設定します。
max_connections
データベースの最大同時接続を設定します。
チューニングではありませんが、プライマリキー以外のキーでSELECTを行うとコストがかかることがあるので、PostgreSQLのコマンドラインツールでインデックステーブルを作成するとよいでしょう。
CREATE INDEX name ON tablename(columname);
nameの部分に任意の名前を設定し、インデックスを作成したいテーブル名tablenameと対象のカラム名columnameを設定します。
具体的な操作手順も掲載しておきます。
一般ユーザーからrootでログイン。
% su
さらにpostgresユーザーでログイン。
# su - postgres
コマンドラインツールpsqlを起動。database_nameはデータベース名を設定。
$ psql -d database_name
インデックステーブルの確認。
=# \di
インデックステーブルの作成。
=# CREATE INDEX name ON tablename(columname);
コマンドラインツール終了。
=# \q
5.チューニングのポイント
複数の項目をチューニングする場合のポイントです。
バックエンドの値をフロントエンドと同等かそれ以上にします。バックエンドで処理が詰まるとフロントエンドで待ち合わせやエラーが発生するためです。
例えばApacheのMaxClientsを30にしているにもかかわらず、Railsアプリケーションの最大プロセス数PassengerMaxPoolSizeを10にしている場合などです。
また、チューニングは複数の項目を同時に変更せず、1項目ずつ。複数の項目を同時に変更するとどの変更で効果があるのか分からなくなるためです。
- Rubyで実行ラインのトレース結果をファイルに出力する方法
- ソースからビルドしたrubyをアンインストールする方法