ククログククログPassengerでRroongaを使ったWebアプリケーションを動かすときにチューニングのコツRroongaはSQLite3のような手軽さで使えるRuby用の全文検索ライブラリーです。Webアプリケーションに全文検索機能をつけたいときにも便利です。Rubyのリファレンスマニュアルの検索サービスであるるりまサーチもRroongaを使っています。そんなRroongaをPassengerで動かすときのチューニング方法を紹介します。チューニングすることにより少ないリソースでも高速に動作するようになります。例として、docs.ruby-lang.orgにデプロイされている、るりまサーチを使います。環境docs.ruby-lang.orgの環境は次の通りです。4.0.48このマシン上で、Rubyのリファレンスマニュアル(HTML)とるりまサーチが動いています。チューニング前の状態まず、チューニング前の状態を説明します。当時のシステムの統計情報をグラフ化したものを見てください。CPU使用率がほぼ0%になっているときはるりまサーチが落ちている状態です。動いているときはCPU使用率50%から100%くらいの状態がほとんどで、そのうちの半分いかないくらいがiowaitです。ロードアベレージは1から5の間なので、常に数プロセス待っている状態です。メモリー使用量は常にほぼ100%です。スワップも半分いかないくらい使っています。メモリ使用量がガクンと減っているときはサービスが落ちているときです。Killerが動いている状態でした*1。チューニング後の状態この状態をチューニングした後の統計情報のグラフを見てみましょう。グラフの真ん中あたりがチューニングを始めた頃です。左半分を見るとチューニング前の状態、右半分を見るとチューニング後の状態がわかります。CPU使用率は20%くらい下がっています。それもよいことですが、それよりも特筆すべきはiowaitがほとんどなくなっているところです。ロードアベレージは常に1より小さくなりました。処理待ちのプロセスはほとんどいないということです。メモリー使用率は半分くらいになりました。スワップも使わなくなっています。iowaitがほとんどなくなっているのはスワップを使わなくなったからです。Killerも動いていません。チューニング方法この改善のためにはPassengerの設定を2つ追加しただけです。100それぞれのパラメーターについて何をするものか、どういう効果があるものかを説明します。passenger_max_pool_sizepassenger_max_pool_sizeはRackアプリケーションのプロセスを最大でいくつ起動するかを制御するパラメーターです。デフォルトは最大で6プロセスです。1つのPassengerで1つのRackアプリケーションしか扱っていないケース(今回のケース)は、このパラメーターの値は多くてもCPU数と同じにするのが適切です。プロセス数がCPU数よりも多くても、CPU数以上同時に実行できないのでそれほど性能はあがりません。プロセスを起動すればするほど使用メモリー量は増えます。今回のケースのようにそれほどメモリーがない環境では、使用メモリー量が増えてスワップを使うようになるとiowaitが発生し一気にパフォーマンスが落ちます。このようにプロセス数を増やす方が遅くなることがあります。チューニング前の状態はまさにこの状態でした。そのため、このpassenger_max_pool_sizeというパラメーターをCPU数と同じ2にするだけでチューニング後のグラフの状態になりました。メモリーが少ない環境では重要なパラメーターです。Rroongaを使ったアプリケーションはプロセス内でデータベースを開くため、メモリー使用量が大きめになります*2。そのため、このパラメーターは重要です。passenger_max_requestspassenger_max_requestsは、指定した数だけリクエストを処理したらそのRackアプリケーションプロセスを終了し、新しいRackアプリケーションプロセスを起動するようにするパラメーターです。デフォルトは0で、この機能は無効になっています。このパラメーターはリクエストを処理するごとにメモリー使用量が増えていくRackアプリケーションに有効なパラメーターです。passenger_max_pool_sizeでベースのメモリー使用量を削減できます。passenger_max_requestsは継続して動作したときのメモリー使用量を削減できます。チューニングを開始した時点のるりまサーチはリクエストを処理するごとにメモリー使用量が増えているようでした。100として100リクエスト処理するごとにプロセスを再起動するようにしました。100は回避策であり、根本的な解決ではありません。根本的に解決した方が助かる人が増えます。そのため、根本的な解決にも取り組みました。Rroongaのメモリー使用量削減るりまサーチが使っているライブラリーは主に全文検索ライブラリーのRroongaです。そのため、るりまサーチのメモリー使用量がリクエストごとに増えているなら次のどれかのコンポーネントが問題です。RubyPassengerRroongaるりまサーチRubyとPassengerは多くの環境で使わているので見逃されているメモリーリークに遭遇する可能性は低いです。そのため、Rroongaとるりまサーチを調べました。詳細は省略しますが、Rroongaの一部がRubyのGCと相性の悪い実装になっていました。長生きしているオブジェクトが一時オブジェクトを参照しているため、RubyのGCが回収できていませんでした。詳細は省略しますが、Rroonga本体を修正し、RubyのGCが動いたときに一時オブジェクトが回収されるようにしました。4.0.4に含まれる予定です。100という設定は無効にしています。この状態で1週間ほど動いていますが、メモリー使用量は170MBほどで安定しています。4.0.4がリリースされたらぜひ試してみてください。まとめPassengerでRroongaを使ったWebアプリケーションを動かすときのチューニングのコツを紹介しました。ポイントはpassenger_max_pool_sizeです。CPU数と同じにして様子を見てみてください。メモリー使用量が大きくなるようならCPU数よりも少なくしましょう。4.0.4ではGCフレンドリーになっています。長時間動き続けるRroongaを使ったプロセスを持っている人は楽しみにしていてください。アップデートできない人はpassenger_max_pool_sizeの使用も検討してみてください。Rroongaに限りませんが、回避策を使うよりも、根本的な解決をする方が助かる人が増えることは事実です。根本的な解決にもチャレンジしてみてください。自分で直すことが難しい場合でも、問題を報告する、デバッグに協力するなどで根本的な解決につながる活動をできるかもしれません。/var/log/messages調べ。データベースファイルはmmapでマップしてアクセスしているので複数プロセスでデータベース用のメモリー領域を共有します。そのため、データベースのサイズ分のメモリーは複数プロセスで共有します。4.0とGFDLのデュアルライセンスで自由に利用できます。クリアコードはプログラミングが楽しいソフトウェア開発者を1名募集しています。クリアコードは「クリアコードをいい感じにする人」を1名募集しています。クリアコードはフリーソフトウェア開発で培った技術力を提供しています。Thunderbird)とRubyとGroonga(全文検索)に関連した開発を得意としています。