ApahceのServerLimitディレクティブ

これまでprefork MPMで使っていたApacheを、負荷増加のためworker化することにした。(MPMについては以前のブログ)で紹介した。そんなわけでhttpd.confのMPMに関する設定値を再検討することになったわけだが、ServerLimitのディレクティブのMPMにより違いをうっすらとしか覚えていなかったのでもう一度調べてみた。

  • prefork MPM の場合
    • ServerLimitはApacheプロセス稼働中におけるMaxClientsに設定可能な上限値を設定する。これは、preforkの場合は「同時クライアント数 = サーバプロセス数」になるため。
    • prefork MPM では、MaxClientsを256 (デフォルト) よりも大きな値に設定する必要がある時にだけ使用する。 希望の MaxClients数とくらべて、必要以上に大きな値を指定することは避ける。
  • worker MPMの場合
    • ServerLimitはThreadLimitディレクティブと組み合わせて、 Apacheプロセス稼働中における MaxClientsに設定可能な上限値を設定する。 再起動中にこのディレクティブを変更しても無視されるが、 MaxClientsは再起動中に修正することができる。
    • worker MPM(leader, threadpool MPMでも同様)では、MaxClientsとThreadsPerChildの設定で 16サーバプロセス (デフォルト) 以上必要になる場合にのみ使用する。希望の MaxClientsとThreadsPerChildとくらべて、必要となるサーバプロセス数以上に大きな値を設定することは避ける。つまり、以下の関係で最大サーバプロセス数がデフォルトの16よりも大きい場合に設定するのがよい。

MaxClients(総スレッド数) / ThreadsPerChild(1子プロセスが生成するスレッド数) = 最大サーバプロセス数

    • ThreadLimitについて補足
      • ThreadLimitとは、 Apache プロセス稼働中におけるThreadsPerChildに設定可能な上限値を設定する。
      • 再起動時にこのディレクティブの値を 変更しても無視されるが、 ThreadsPerChildは再起動中に、このディレクティブで指定された上限値まで 変更することができる。
      • ThreadLimitディレクティブを使用する際は特に注意が必要。ThreadLimitがThreadsPerChild よりもずっと大きな値に設定された場合は、 余計な未使用共有メモリが割り当てられてしまう。 ThreadLimitがThreadsPerChild の両方がシステムの扱える範囲を超えている場合は、Apache は起動しないか、起動したとしても不安定になる場合がある。 このディレクティブの値は今使用している Apache の ThreadsPerChild の予想上限値を 超えた値には設定してはいけない。ThreadLimit のデフォルト値は mpm_winnt のときは 1920 で、 他の場合は64。
  • ServerLimitディレクティブを使用する際の注意点
    • ServerLimit が必要以上に大きな値に 設定された場合は、余計な未使用共有メモリが割り当てられる。ServerLimit と MaxClients がシステムの扱える範囲を越えた設定値になっていると、 Apache は起動しないか、起動しても不安定になる場合がある。
    • perchild MPM では、 NumServers を 8 (デフォルト) よりも大きな値に設定する必要があるときにのみ使用する。

上記、色々と書いたがサンプルを例に説明する方がわかりやすいと思うので、以下に例を載せる。



ServerLimit 60
StartServers 2
MaxClients 1500
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 1000

この例では、接続可能なリクエスト最大数を1500としているため、前述のディレクティブ同士の関係から、リクエスト上限までアクセスが集中した場合の子プロセス数は最大で「1500(MaxClients)/25(ThreadsPerChild)=60プロセス」となるため、ServerLimitディレクティブの設定値は60となる。なお、ここでは各子プロセスが起動するスレッド数(ThreadsPerChild)はデフォルトの25のままとしている。この値を64よりも大きくする場合には、ThreadLimitディレクティブを使用し、値をセットする。