Apache の MPM とは
Apache サービスを起動すると、httpd プロセスが複数生成されます。
各プロセスはクライアントからの http リクエストを受け付け、処理を行いクライアントへレスポンスを返します。
プロセスを複数生成することで同時にリクエストを処理することができるようになります。これを実現するモジュール(追加機能)のことを Multi Processing Module , 略して MPM と呼びます。
MPM には 3 つの方式が存在します。prefork / worker / event driven (イベント駆動) です。
以降でこれらの違いを解説していきますが、prefork と worker の違いをより理解するためには、プログラム(プロセス)が CPU をどのように使っているのかを知る必要があります。以下の記事に概要を解説していますので併せてご参照下さい。
prefork とは
Apache では昔から prefork という方式が使われています。2019年現在においても CentOS で使える Apache 最新パッケージはデフォルトで prefork になっています。
prefork では 1 つのプロセスが 1 つのスレッドを持ちます。スレッドとは CPU に命令を渡す単位です。
つまり、1 つの httpd は 1 つの CPU コアを使ってリクエストを処理します。このようなプロセスを「シングルスレッドプロセス」と呼びます。
なお、prefork の意味は、「アクセスが増えてきたら前もって (pre) fork する」ということですが、worker であっても event であってもこれは同じです。
fork とは Linux のシステムコールの 1 つで、プロセスから別のプロセスを呼び出すことです。(このケースでは、ある プロセス ID を持つ httpd が、別のプロセス ID となる httpd プロセスを生成することです。)
worker とは
worker 方式では 1 つのプロセスが複数のスレッドを持ちます。これにより、少ないプロセス数で多くの仕事を同時実行できるようになります。このようなプロセスを『マルチスレッドプロセス』と呼びます。
CentOS7.6 の Apache で worker MPM を使うためには以下のように設定します。
[root@localhost ~]# vi /etc/httpd/conf.modules.d/00-mpm.conf
以下をコメントアウト(先頭に#を追加)
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
以下をコメントイン(先頭の#を削除)
[root@localhost ~]#LoadModule mpm_worker_module modules/mod_mpm_worker.so
そして httpd を再起動
[root@localhost ~]# systemctl restart httpd
以下コマンドで worker になっていることを確認できます。
[root@localhost ~]# httpd -V | grep MPM Server MPM: worker
デフォルトでは 1 プロセスあたり 27 個のスレッドを持ちます。1つの親スレッド、1つの子スレッド、25個のスペアスレッドです。スレッド数の確認方法は ps コマンドに -L オプションを使います。(以下の通り)
[root@localhost ~]# ps aux -L | grep httpd root 1462 1462 0.0 1 0.5 224224 5232 ? Ss 21:36 0:00 /usr/sbin/httpd -DFOREGROUND apache 1463 1463 0.0 1 0.2 223972 2936 ? S 21:36 0:00 /usr/sbin/httpd -DFOREGROUND apache 1464 1464 0.0 27 0.5 511052 5500 ? Sl 21:36 0:00 /usr/sbin/httpd -DFOREGROUND apache 1464 1470 0.0 27 0.5 511052 5500 ? Sl 21:36 0:00 /usr/sbin/httpd -DFOREGROUND apache 1464 1471 0.0 27 0.5 511052 5500 ? Sl 21:36 0:00 /usr/sbin/httpd -DFOREGROUND ~~~ 略 ~~~
event (イベント駆動) とは
Event Driven 方式はベースは worker と同じです。異なるのは、プロセスを増やすときの挙動です。
prefork や worker では必要に応じてプロセスを増やすだけですが、event では「プロセス数不足」というイベントをトリガーとして以下のステップでプロセスを増やします。
- 新規プロセスを起動し、以降に来たリクエストは新規プロセスのみで受け付ける。
- 既存プロセスはリクエストの受け付けを止め、速やかにプロセス停止する。リクエスト処理中のプロセスは処理が終わったらプロセス停止する。
これは http KeepAlive により大量な TCP コネクションが無駄に残り続け、(メモリ圧迫や syncookie 等により) パフォーマンス低下を招く、という問題を回避するための挙動です。
http KeepAlive とは、1 つの TCP コネクションの中に複数の http リクエストを乗せるための方式ですが、タイムアウトが来るまでは TCP コネクションが残り続けます。詳細については以下をご参照下さい。
不要かどうかの判断はできないので昔のコネクションは一律に切断し、必要なら再度コネクションを確立してもらうわけです。
CentOS7.6 の Apache で event MPM を使うためには以下のように設定します。(worker とほぼ同じ)
[root@localhost ~]# vi /etc/httpd/conf.modules.d/00-mpm.conf
以下をコメントアウト(先頭に#を追加)
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
以下をコメントイン(先頭の#を削除)
#LoadModule mpm_event_module modules/mod_mpm_event.so
そして httpd を再起動
[root@localhost ~]# systemctl restart httpd
以下コマンドで event になっていることを確認できます。
[root@localhost ~]# httpd -V | grep MPM Server MPM: event
コメント