HTTPはステートレスプロトコルです。クライアント/サーバ間のTCP接続を永続させず、要求に応じて接続の開始/切断を行います。しかし、Webページは通常HTMLドキュメントや画像など、複数のファイルで構成されています。クライアントが1つのWebページを取得する間に、ファイルごとにTCP接続の開始/切断を行うのは大変非効率的です。そこで、KeepAliveを利用して1つの接続を使い回し、複数のリクエストに応えられるようにします。
KeepAliveの動作にかかわる重要なパラメータが以下に挙げる3つのディレクティブです。
「On」にすることで、KeepAliveを有効にします。
KeepAlive On
現在使用されているWebブラウザはApacheのKeepAliveに完全に対応しているため問題はありませんが、マイナーなクライアントや古いバージョンのWebブラウザではApacheのKeepAliveとの互換性に問題が発生する場合があります。そうしたWebブラウザがメインのクライアントとなっている場合は、KeepAliveを「Off」にすることを検討しましょう。
1つのKeepAliveが、開始から切断までに受け付けるリクエスト数を設定するのがMaxKeepAliveRequestsです。
MaxKeepAliveRequests 100
大きな値を設定すると、一度に処理できるリクエスト数が多くなる代わりに、ほかの接続が割り込むタイミングが遅れることになります。1ページの読み込みが完了したらKeepAliveを終了するように、
1ページ当たりの平均的なファイル数+α
をMaxKeepAliveRequestsの数値にするとよいでしょう。
KeepAliveTimeoutは、KeepAliveで接続を維持しているクライアントからのリクエストがなくてもKeepAliveを維持する秒数を指定します。
KeepAliveTimeout 15
値を大きくすると、1ページ分の転送が完了した後もクライアントと接続を維持したままになり、ほかのクライアントへの応答が遅れます。通常は次の値を設定します。
1ページ当たりの平均的な転送時間+α
「1ページ当たりの平均的な転送時間」の算出は、クライアントのネットワーク環境も考慮します。ブロードバンド環境であれば、Webを1ページ表示するのに数秒程度であっても、ナローバンド環境では数十秒になることもあります。
しかし、あまり神経質になる必要はありません。デフォルトの15秒から少しずつ減らしながら調整します。KeepAliveが無駄に残留し、サーバのリソースが消費されることを嫌うなら「2」など、極端な値を設定します。
Apache 2.0はマルチスレッドに対応し、旧来のプロセス処理からパフォーマンスを向上させていますが、デフォルト設定ではプロセスベースの処理になっています。ここでは、プロセスベースで起動されているApacheを前提に、重要な設定項目を紹介します。
ここで紹介する値を設定するには、メモリやプロセスの使用状況を把握しておく必要があります。その方法については後述します。
<IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 256 MaxClients 256 MaxRequestsPerChild 4000 </IfModule>
Apacheは複数のプロセスを起動し、同時に多くのリクエストに応じます。当然、起動しておくプロセスが多いに越したことはありませんが、使用されないプロセスでリソースを消費するような無駄は避ける必要があります。しかし、リクエストが発生してから新たなプロセスを立ち上げていたら、レスポンスが悪化します。
プロセスはサーバに大きな負荷を与え、起動には時間を要します。そこで待機プロセスを用いて、サーバのリソースが無駄にならない程度のプロセスをあらかじめ立ち上げておき、要求に備えるようにします。Apacheは、待機プロセスの消費に応じて動的にプロセス数を調整することができます。これらの動作に必要なパラメータが下記のディレクティブです。
StartServersは、Apacheを立ち上げた際に最初に起動するプロセス数です。サーバの立ち上げと同時に高アクセス数を記録するようなら、この値は後述するMaxClientsに近い値を設定する必要があります。しかし、待機プロセスは以下で紹介するMinSpareServers/MaxSpareServersの値に応じて動的に調整されるため、デフォルトの5〜10の値で十分です。StartServersの値を増やすと、Apacheの起動時間が長くなりサービスのダウンタイムが大きくなります。
StartServers 5
StartServersの変更に当たっては、デフォルト値の場合と数を増やした状態とで、1プロセス当たりの起動にどれくらいの時間差が発生するかを調べておきましょう。調査結果は、MinSpareServers/MaxSpareServersの設定の参考になります。
Apacheは、MinSpareServers値〜MaxSpareServers値のプロセスが常時待機しているようにプロセス数を調整します。待機プロセスが消費されそうになると、新たなプロセスを生成します。
MinSpareServers 5 MaxSpareServers 10
MinSpareServers/MaxSpareServersは、過度な待機プロセスが発生しないように、
MinSpareServers < MaxSpareServers
になる値を設定します。
待機プロセスを使い切り、新たなプロセスの起動が間に合わない状況になっているなら徐々に値を上げ、消費されるプロセス数と起動するプロセス数のバランスを保つようにします。下で紹介しているMaxClientsの値まで上げることもできますが、無駄に高い値を設定して待機プロセスでサーバのリソースを浪費しないように注意しましょう。
error_logに
[Thu Aug 25 19:40:06 2005] [error] server reached MaxClients setting, consider raising the MaxClients setting
のようなエラーが出力されるようなら、MaxClientsの値を上げる必要があります。ただし、ServerLimitより大きな値を設定することはできないため、MaxClientsの値を上げる際は併せてServerLimitも変更する必要があります。
ServerLimit 150 MaxClients 150
Apacheは、最大でMaxClients個のプロセスを起動させます。高アクセスのサーバでは当然高い値を設定し、クライアントの要求に応えられるようにする必要があります。ただし、高い値にし過ぎると、メモリを使い切りスワップが発生するなど、かえってレスポンスが悪化します。MaxClientsの設定に際しては、以下の式が目安になるでしょう。
MaxClients=使用可能なメモリ量/Apacheの1プロセスが使用するメモリ量
式は単純ですが、事前に「使用可能なメモリ量」と「Apacheの1プロセスが使用するメモリ量」を正確に算出するのは大変難しい作業です。
「使用可能なメモリ量」は、サーバに搭載されているメモリから、OSやApache以外のプロセスが使用するメモリを引いた値になります。「Apacheの1プロセスが使用するメモリ量」を算出するのはさらに難しく、また画像やHTMLファイルだけの静的なコンテンツの場合とPerlやPHPなどの動的コンテンツの場合とでは使用するメモリ量も変わってきます。共有メモリ分を加味する必要もあるでしょう。経験的には、静的コンテツの場合で数Mbytes、動的コンテンツで20〜30Mbytesと大きな差があり、平均を求めるのは骨が折れます。
そこで、値を少しずつ上げていき、vmstatやtopなどのコマンドでスワップへの書き込みが発生しない値を調べる必要があります。vmstatやtopコマンドの使い方については、Linux Tips「メモリの使用量を調べるには」を参照してください。
起動できるプロセス数には、OSの限界もあります。OSの限界を超えるMaxClientsを設定することはできません。Linuxでは、ulimitコマンドでこれを確認できます。変更もulimitコマンドを使用します。
# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited pending signals (-i) 8063 max locked memory (kbytes, -l) 32 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 8063 ←最大プロセス数 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
# ulimit -u 10000 ←max user processesの値を10000に変更 # ulimit -a ←確認 ... max user processes (-u) 10000 ←変更後
CGIやPHPなどを使った動的コンテンツを使用していると、Apacheのプロセス数は増えていないのに使用メモリが増えていく現象に遭遇することがあります。これはメモリリークを引き起こすようなプログラムを動的コンテンツ内で使用しているためです。例えば、データベースとの接続を必要とするプログラムが、データベースの操作後も接続を解放しないなどの原因が考えられます。
プログラムを見直すことが第一ですが、Apache側でも使い回しているプロセスを定期的に再起動させることで、取りあえずはメモリリークを防ぐことができます。メモリリーク以外にも、プロセスを定期的に再起動することでコンテンツの不具合が改善されることがあります。これらの場合は、MaxRequestsPerChildで再起動タイミングを設定します。
MaxRequestsPerChild 0
再起動タイミングは、不具合の程度にもよりますが、なるべく「5000」や「6000」といった大きな値を設定します。指定が「0」の場合は無制限を意味し、プロセスの再起動は行われません。画像やHTMLドキュメントのみで構成された静的コンテンツの場合は、「0」のままで使用します。
なお、不用意に値を設定すると、プロセスの再起動に引っ張られてサーバのパフォーマンスやクライアントへのレスポンスが低下します。
Copyright © ITmedia, Inc. All Rights Reserved.