QA@IT

passenger_pool_idle_time を 0 にしたときの挙動について

2842 PV

passenger の passenger_pool_idle_time(apache なら PassengerPoolIdleTime)を 0 にすると、本当に必要になったとき以外はインスタンスをシャットダウンしないとドキュメントに記載があります。シャットダウンする例として、「inactive なインスタンスを他のアプリケーションのインスタンスに移し替える」という記載がありますが、その他にインスタンスをシャットダウンするケースはあるでしょうか。

もし、特にシャットダウンすることなく長時間経過した場合、メモリの使用量がメモリリーク等の要因で大きくなりすぎるのではないかと心配しています。

回答

passenger以外のunicornやthinなどのアプリケーションサーバは(monitやgodなど外部モニタリングツールを使わない限り)勝手に再起動することはありませんから、むしろpassenger_pool_idle_time=0のほうが一般的な挙動だといえると思います。数分間アイドリングしただけで次のリクエストが妙に重い、というのは、ユーザ体験としてもあまり望ましいものではないですし。

passenger_pool_idle_timeが役に立つ局面は、単一OS上でトラフィックにばらつきのある大量のアプリを共存させるような大規模ISPのレンタルサーバで使われるようなユースケースをイメージするのがよいかと思います。一般的なアプリケーションでは、swapしないようにきっちりサイジングするのが通例だと思いますので、空きメモリができても特に嬉しいことはなく、時々重くなるというペナルティが目立つだけで、この設定にはまず出番がないと思います。

メモリリークを心配されてるようですが、たしかにRails 1.x-2.xの頃はプロセスのサイズがどんどん膨れ上がるmemory bloatが大きな問題でしたが、Rails 3.x以降ではRMagickなど一部の筋悪ライブラリを使わないように気をつける&ActiveRecordのインスタンスを一度に10,000件以上ロードしないようにする(find_in_batchesをつかう)、などの基本的なポイントをおさえておけば、まずbloatは起きません。どうしても大規模にヒープを確保する必要がある処理は、どのみち非同期でやりたいでしょうから、Resqueのように毎回fork/exitするバックグラウンドツールを使えばメモリをクリーンに保てるでしょう。

それでも、サーバを運用していると様々な問題が起きますから、やはり監視と通知は欠かせません。monitやgodにプロセスごとのメモリ使用量を監視させたり、あるいは実際にじわじわリークしているなら定期的にtouch restart.txtしてやる、などの防衛的対策は、いずれにせよ検討する必要があると思います。

ちなみに余談ですが、メモリ節約術で一番大事なのはアプリケーションサーバに32bit OSを使う、ということだったりします。Passenger+REEによる節約よりはるかにお手軽で効果的だったりします。

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。