Apache の並列数を CPU コア数に応じて決定する
KLab Advent Calendar 2011 「DSAS for Social を支える技術」の10日目です。
昨日の記事 では並列数を設定する基本的な方法を紹介しました。 今日は実際に DSAS for Social で利用している設定方法を紹介します。
背景
実際の並列数の設定はマシンのCPUスペックやアプリの特性(レスポンスタイムの 何割をWebサーバーのCPUを使う処理が占めているか)に応じて設定するのですが、 DSAS for Social ではアプリの負荷に応じて柔軟にWebサーバーを 追加・削除するので、CPUスペックが一定ではありません。 具体的に言えば、 Core2 世代の4コアサーバーと、Core i7世代の4コア8スレッド サーバーが Web サーバーとして利用されています。
でも、Webサーバーごとに違う設定ファイルを用意したくはありません。 なんとかできないかと思っていたところ、 @hamano が httpd.conf 内で環境変数が 使えるよ、と教えてくれました。
CPUコア数から並列数を計算し設定する
DSAS for Social では daemon tools を使って Apache を起動しています。 なので、 run スクリプトでコア数に応じて並列数を計算します。
あるMVCフレームワークを使ったCPU使用率の高いphpアプリでは、 コア数+2 に設定しています。(Core2世代4コアなら6並列、Core i7世代4コア8スレッド なら10並列になります)
CPUCOUNT=`getconf _NPROCESSORS_ONLN` export MAX_CLIENTS=$((CPUCOUNT+2))
次に、httpd.conf でこの環境変数を利用して並列数を設定します。
MinSpareServers ${MAX_CLIENTS} MaxSpareServers ${MAX_CLIENTS} StartServers ${MAX_CLIENTS} ServerLimit ${MAX_CLIENTS} MaxClients ${MAX_CLIENTS}
これで Web サーバーを40台まで増やしても MySQL の接続数は400以下に抑えられますし、 実際にCPU使用率が80%以上になってレスポンスタイムが伸びてきても安定して サービスが継続できています。
補足: ProxyPass の connectiontimeout を1秒未満に設定する
昨日の記事で使っていたテスト環境は apache 2.2.10 を利用していたのですが、 connectiontimeout パラメータは 2.2.10 で導入された後、 2.2.11 から ms という サフィックスを付けて1秒未満の値を設定できるようになりました。
ループバックアダプタへの接続は backlog が足りていたら 1ms もかからないので、 "connectiontimeout=10ms" などに設定したらいいと思います。