のチューニングについて

http://www.atmarkit.co.jp/flinux/rensai/apache15/apache15a.html
http://tech.bayashi.net/svr/doc/apache/tune.html

MPM

  • apache を起動すると、root権限で httpd の親プロセスが1つ起動し、複数個の子プロセスが root ではない権限で起動する。
  • 子プロセス数は変動する。
  • 親プロセスは well-known ポートで待ち受けるため root で起動。
MPM 説明
prefork 1つのリクエストに対して1つのプロセスが応答する。Apache 1.3 系ではこれが使われている
worker スレッド型。1つのリクエストに対して1つのスレッドが対応する。1プロセスあたりのスレッド数は固定。
prechild スレッド型。worker と異なるのは、子プロセスの数は固定で、1つのプロセスの中のスレッド数が可変。子プロセスごとにユーザ権限を分けられるのでホスティングには効果的(だが今はまだ時期尚早)
winnt スレッド型。Windowsに特化している

どれを使うかと言われたら、prefork か使っても worker。

インストール

各モジュールを組み込むのか DSO (Dynamic Share Object) としてコンパイルするのか。
後者のほうが httpd がメモリ上に配置されたときのメモリ消費量が異なる。
ただし、実測するといずれもパフォーマンスはあまり変わらない。

チューニング

  1. 現状を調査し問題点を発見
  2. 解決策の実施
  3. 動作確認

経験値をつむまでは論理的な思考で解決策を導き出す。
無理な策、極端な策は講じない。

ボトルネック

  1. ディスク
  2. ネットワーク
  3. 名前解決
  4. 子プロセス数が少なく waiting になる
  5. プログラム

ボトルネックがCPUの速度になるのが理想的。つまり、他の問題が全部解決したという証拠。

パフォーマンスをどう見るか

  • 単位時間(秒)当たりの最大接続数→サーバ側で、ログやpsで測定する
  • 最大転送バイト→単位時間あたりの転送ファイルバイト数
  • RTT→クライアント側で測定し、リクエスト出してから返事があるまで8秒以内

パフォーマンスを測定

  • ab(apache bench)やJMeterを使って、一時的に高負荷状態を作り性能限界を確認する
  • 長い時間幅でアクセスパターンを元にwebサーバの利用情報を確認する(AWStats, Analog)

システム状況

コマンド 内容
ps, pstree プロセスの確認
top, uptime CPU利用率
free メモリ利用率
ipcs 共有メモリやセマフォの情報
vmstat メモリの状況
sysstat
sar システム動作状況
iostat ディスクの利用状況
mpstat プロセッサの統計情報
ab -c 100 -n 500 http://127.0.0.1/
vmstat 10 20 
iostat -d -x sda 5
free

freeコマンドの出力結果は、Memory の used は disk cache を加えたもの
>|-/+ buffer|< の free が0に近づくと危険

チューニングする

  • ボトルネックがどこにあるのか、常に監視する
  • 回線かも
  • マシンスペックかも
  • NiC を変更するだけで変わる
  • 設定を見直す(デフォルトの設定は無駄がいっぱい)

子プロセス数の調整

同時リクエスト処理数は子プロセス数(prefork)、スレッド数(worker)で決まる

項目 内容
StartServers Apache起動時の子プロセス数
MinSpareServers 待機中の子プロセスの最小数
MaxSpareServers 待機中の子プロセスの最大数
MaxClients 子プロセスの最大数 (〜256:ソースで指定)
MaxRequestsPerChild 1つの子プロセスが処理できるリクエスト数。この値を越えたらプロセスは再起動。暴走防止のため。1000万とか1億くらいにしておく

子プロセスは一機に作ろうと努力するが、意外に時間がかかるもの。不要になったプロセスは1秒に1個ずつ減っていく。

keepalive

keepalive を on にしておくと、1リクエストごとに接続を切らずにしばらくは接続を保持することができる。しかし、もう接続が来ないが接続を保持しておかないといけないので、リソースの無駄使い。

keepalive を off にしておくと、1リクエストごとに接続を切る。最近では、keepalive なサイトに対しては、最初から複数のリクエストを発行するブラウザもある。

よって、keepalive を on にして、タイムアウトの値を長くしすぎないようにする。1ページのレンダリング時間を計測しそれに少しだけ余裕のある程度とする。