ApacheのMPMについて

今日はApacheのMPMについて書いてみる。MPMは、Apache HTTP サーバではリクエストを処理する部分のことを指し、Apacheを使用する上でMPMはとっても大事なもの。Apache HTTP サーバ 2.0系から採用されている。MPMの種類は以下の4通り。

  1. prefork
  2. worker
  3. perchild
  4. winnt

【参考】ApacheのMPMの確認方法だが、Linux環境でのMPMの確認例は以下の通り。


# /usr/sbin/httpd -l
Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c

prefork MPM

一番代表的な prefork MPM について。prefork MPM の特徴は、次のとおり。

  • Apache HTTP サーバ 1.3 系以前のモデル
  • 1 つのリクエストに対して、1 プロセスを割り当てる
  • 負荷に応じて、子プロセスを増減させる

prefork MPM は、worker MPM と同じくらいよく使われる MPM 。PHP で使うときは、PHPで書かれたwebサービスを高速化するにあるとおり、prefork MPM を使う必要がある。PHP を使うとき、worker MPM を使うことは推奨されていないので注意する。prefork MPM では、ServerLimit と MaxClients は同じ値を設定する。

<prefork MPM のデフォルト設定>


StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000

関連するディレクティブの説明は、次のとおり。

  • StartServers: 最初に起動する子プロセスの数
  • MinSpareServers: 待機する子プロセスの最小数
  • MaxSpareServers: 待機する子プロセスの最大数
  • MaxClients: 生成する子プロセスの最大数
  • MaxRequestsPerChild: それぞれの子プロセスが扱うリクエスト数の制限数

<本番実装例>


StartServers 8
MinSpareServers 5
MaxSpareServers 30
ServerLimit 300
MaxClients 300
MaxRequestsPerChild 50

上記例では、MaxRequestsPerChild の値が小さいのが特徴。MaxRequestsPerChild を小さくしている理由は、PHP を使っているとかなりメモリを消費するため、頻繁に子プロセスを生成しなおしたいため(らしい)。prefork MPM を使う場合、大量のアクセスを捌きたい場合には MaxClients の値を増やせばいいが、あまり増やしすぎてしまうとメモリ不足などになることが多いので、MaxClients を増やすときは ab(Apache Bench) コマンドなどを使って負荷テストを粉って、どのくらいまで設定できるのか見極める必要がある。

Worker MPM

次に workder MPM について解説。worker MPM の特徴は、次のとおり。

  • スレッド対応型
  • リクエスト処理は、スレッドが対応する
  • 負荷に応じて、子プロセス数を増減させる
  • 1 子プロセスあたりのスレッド数は固定になっている

worker MPM は、子プロセス数を増減させるというところは prefork MPM と似ているが、リクエスト処理をスレッドが対応するというところが大きく違っている。worker MPM は子プロセスを生成したとき、リクエスト処理をするスレッドを最初にすべて生成するので、新しいリクエストがきたとき、prefork MPM のように子プロセスの生成を待つ必要がないので prefork MPM よりパフォーマンスがよい。

<worker MPMのデフォルト設定>


StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0

関連するディレクティブの説明は、次のとおり。

  • StartServers: 最初に起動する子プロセスの数
  • MinSpareThreads: アイドル状態のスレッド最小数
  • MaxSpareThreads: アイドル状態のスレッド最大数
  • MaxClients: 同時に応答することのできるクライアント数の最大数 (つまり全プロセス中の総スレッド数の最大値)
  • ThreadsPerChild: 子プロセスそれぞれに生成されるスレッド数
  • MaxRequestsPerChild: それぞれの子プロセスが扱うリクエスト数の制限数

perchild MPM

perchild MPM の特徴は、次のとおり。

  • スレッド対応型
  • リクエスト処理は、スレッドが対応する
  • 負荷に応じて、スレッド数を増減させる
  • 子プロセスの数は固定になっている

perchild MPM は、worker MPM の反対のような特徴をもっており、スレッド数だけが増減する仕組みとなっている。
そのため、子プロセスの生成を待つ必要がなく、スレッドも必要なだけになるため、もっともリソースを有効に使うことができる MPM といえる。ただし、prechild MPM は不安定な面もあるという情報があるので、本番環境で使う前には入念なテストが必要。

winnt MPM

winnt MPM の特徴は、次のとおり。

  • スレッド対応型
  • リクエスト処理は、スレッドが対応する
  • Windows NT に特化したスレッドモデル

winnt MPM は、その名の通り Windows NT 向けに特化した MPM 。Windows 上の Apache HTTP サーバでは、winnt MPM がデフォルトで使われる。このMPMは、マルチスレッド化し処理を行うためのプロセスを生成することはない。関連するパラメータは以下の通り。

  • ThreadsPerChild:子プロセスそれぞれに生成されるスレッド数。デフォルト値:250
  • MaxRequestsPerChild:子サーバプロセスが扱うことのできるリクエストの制限数。デフォルト値:0(無限)

補足

  • prefork MPM より worker MPM の方がパフォーマンスが高い理由
    • リクエスト処理をするために子プロセスを生成するではなくスレッドを使うところがポイント。詳しくはまた後日。