by shigemk2

当面は技術的なことしか書かない

サーバ/インフラを支える技術4 Apacheのチューニング

前回
サーバ/インフラを支える技術4 Linux単一ホストの負荷を見極める 3 負荷の軽減について - by shigemk2

デファクトスタンダードになっている
Apache HTTP SERVER(Apache)のチューニングについて

例によって、チューニングによって、性能が2倍3倍になるわけではないことは
重々承知のこと。

過負荷でwebサーバが応答を上手く返せない場合、
原因はwebサーバの設定とは関係のないことが殆どである。
なせなら、webサーバの応答不能は結果であって、原因ではないから。

Apacheには並列処理を行うモデルがあり、

  • プロセスを複数生成するマルチプロセスモデル
  • スレッドを複数生成するマルチスレッドモデル
  • 入出力を監視してイベント発生のタイミングで処理を切り替え、シングルスレッドで並行処理を行うイベントドリブンモデル

などがある。
Apacheでは内部の各種機能がモジュールにより綺麗に分離されているが、
並行処理を行うコア部分の実装もモジュール化されている。
MPM(multiprocessing module)と呼ばれるモジュールがそれである。

UNIXにおいて代表的なMPMは、
prefork: あらかじめ複数のプロセスを生成(プリフォーク)して、クライアントの接続に備えるマルチプロセスモデル(安定指向かつ後方支援性が高い)
worker: マルチプロセスとマルチスレッドのハイブリッド(スケーラビリティが高い)

デフォルトはpreforkで、/etc/sysconfig/httpdで設定を変更可能。

ただ、プログラミング的には、メモリ空間を共有するためリソース競合が発生
しうるマルチスレッドのプログラミングは複雑になりがちである。
そのため、preforkにしか対応していないサードパーティ製のモジュールも存
在する。

また、メモリ空間を共有するマルチスレッドのほうがメモリ消費量は少なく、
またスレッド切り替えにかかるコストもマルチプロセスより少ない。
(この処理をコンテクストスイッチという)

ただ、preforkをworkerに変更しても、

  • 1つのクライアントに対する応答時間は高速化されない(コピーオンライト)
  • メモリが十分にあれば同時に扱える接続数も変わらない
  • 大量のコンテクストスイッチがなければ効果は大きくない

ただし、

  • メモリ容量があまり多くない場合
  • メモリ消費量を少なくすませたい場合
  • コンテクストスイッチの回数が多い場合

は、workerのほうがパフォーマンスは高い



MaxClients 同時に接続できるクライアント数の上限値を設定することで、
スレッド/プロセスを生成しまくって応答不可能になる最悪の事態を回避でき
る。

リクエストが多すぎる場合は、

  • 処理しきれないリクエストには待ち行列の中で一定時間待ってもらい、
  • さらに待ち行列があふれるようならそのリクエストにはエラーを返却する

preforkの場合、MacClientsのほかにプロセス数の上限を静的に設定する
ServerLimitの2つで安全弁となっている。

(ただし、この2つの値に、絶対的な基準は存在しない。マシンの性能によって
設定を変える必要がある)


コピーオンライト
プロセスをforkで生成するときは、各プロセスに親子の関係を構築する。
親と子は別のメモリ空間で動作し、互いが干渉することもない。
これを実現するために親から子へプロセスをコピーされるのだが、メモリの無駄遣いであるため、
コピーオンライト(仮想メモリ空間のみ別々にし、物理メモリ空間は共有する)
を利用する。

workerの場合、

  • 1つのプロセスの中に複数のスレッドを生成し、スレッド1本でクライアント1つを処理する
  • そのプロセスを複数生成する

という動作をする。ただしコピーオンライトは行わず、1スレッドあたり
スタック領域として最大8192kbのメモリを必要とするが、チューニング方法は
preforkと変わらない。

また、workerの安全弁として、

  • MaxClients 同時に接続できるクライアントの上限、プロセス×スレッド
  • ServerLimit プロセス数の上限
  • ThreadLimit プロセスあたりのスレッド数の上限
  • ThreadsPerChild (ThreadLimitとほぼ同義)

ServerLimit≧MaxClients/ThreadsPerChild
となるように設定を行う。これが満たされていない場合は
エラーログにその旨が記録される

ただし、webサーバの設定をいくら変更しても例えばDBの過負荷が原因の場合
は、MaxClientsをいくら増やしてもクライアントの要求が多すぎるから
結局ブロックされる。

故にwebサーバのエラーは問題の結果であって原因ではないことが多い。
また、Keep-Aliveがボトルネックの原因になることもある。


Apacheは綺麗にモジュール化されていて汎用性の高い作りになっているた
め、拡張モジュールの開発が盛んで使いやすい。
ただし、1リクエストのサイクル内に要するリソースがCPU計算量、
メモリ消費量ともに若干大きく、その大きいリソース消費量が
プロセス/スレッド分だけ必要になる、という欠点がある。


これに対しlighttpdは、

  • Apacheに比べて汎用性は劣るが、1リクエスト数あたりの計算量は少ないのでCPUに優しい
  • シングルプロセスなのでメモリ消費量がApacheに比較して圧倒的に小さい
  • Apacheのコアモジュールに相当する基本的な機能は全てカバーしている
  • Ruby,Perl,PHPで記述されたwebアプリケーションを高速化してAPサーバとして活用できる。

などの利点もあるので、もし大量のクライアントからの接続を少ないリソースで
処理したい場合はlighttpdを検討するのもよい。

次回
サーバ/インフラを支える技術4 MySQLのチューニングのツボ - by shigemk2

[24時間365日] サーバ/インフラを支える技術 ?スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)

[24時間365日] サーバ/インフラを支える技術 ?スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)