2020/11/14 Apache MPM
MPM
Apacheにはリクエストを受けた際の処理方法を決める動作モードのようなものがある。
その設定をMulti Processing Module(MPM)という。
MPMの種類としては、
worker
event
prefork
の3つが存在する。
CentOS7ではインストール時のデフォルトでpreforkが設定される。
しかし、CentOS8ではeventに変更された。
これらについて詳しく確認する。
シングルスレッド、マルチスレッド
MPMを理解するにはマルチプロセス、マルチスレッドについての理解が必要。
重要なキーワードとして、プロセス、スレッド、コアがある。
プログラムが実行されると、プロセスが立ち上がる。
このプロセスには1つ以上のスレッドが含まれている。
コア
CPUの脳みその部分。
複数の処理を同時実行はできない。
スレッドから受け取った命令を計算する。
Intelにはハイパースレッディングと呼ばれる、OSから見た際に論理的にコアを増やす。
例えば、4コア8スレッドのCPUはOSから見ると、8コアあるようにみえる。
つまり1コアで2スレッドの実行を行うことができる。
※実際にコアがあるわけではないので性能が2倍になるわけではなく、アイドルタイムを有効に活用している。
プロセス
プロセスとはプログラムそのもの。
プロセスはメモリ領域をもっており、これはOSによって管理される。
プロセス毎に独立したメモリ領域をもっているという事実が非常に重要。
スレッド
スレッドとはCPUに対して命令を渡すことのできる実行単位。
シングルスレッドでは問題が起きないが、マルチスレッドで問題が起こる場合がある。
スレッドはプロセス内のメモリ領域を共有するため、
スレッド同士がメモリ領域を書き換えてしまうと問題が起こるので
プログラミングをする人はスレッドセーフな設計を行う必要がある。
具体的には、排他制御等を行う。
シングルスレッド
シングルスレッドとは、プロセスに一つのスレッドが含まれている形。
HTTPのREQUESTが届くと、スレッドが待ち受ける。
このスレッドがCPUのコアに対して命令を渡す。
プロセスひとつひとつがメモリを専有するため、プロセス1つがおかしくなっても
周りに影響がない。
また、スレッドの並列処理がない逐次処理のため、問題が発生しない。
https://gyazo.com/7cdac32786b5ae587464fd0f3f6c50f0
マルチスレッド
マルチスレッドは1つのプロセスに複数のスレッドが存在する。
このスレッドという単位でCPUコアに命令を出せるので、
並列処理が可能になる。
マルチコアのCPUにおいて、スレッドがそれぞれコアに割り当てることができるので高速化できる。
しかし、コアが1つしか無い場合、パフォーマンスが上がらない。
また、並列処理では、完全な並列処理ではなくものすごい速さでスレッドを切り替えている。
プログラムによってはバグを引き起こす可能性がある。
https://gyazo.com/05c78fb5a6a07a9f824b480d37e86381
以上の内容を踏まえた上で、MPMを確認する。
MPM
prefork
preforkとは「シングルスレッド」で動作する形式。
https://gyazo.com/cbd9f76bbe9e2e033df0756635bb4849
名前の通り、事前(pre)にフォーク(fork)するという意味で、
コントローラプロセスが、アクセスに合わせて子プロセスを作成(フォーク)する。
特に、CentOS7まで標準ではprefork。
これはApacheで利用されている「mod_php」に関してスレッドセーフではないため、
preforkを使うほかなかった。
worker
workerは複数のプロセスを起動しておく点ではpreforkと変わらない。
しかし、「マルチスレッド」で動作する点が大きく異なる。
1つのプロセスの中に、ワーカースレッドとリスナースレッドが存在し、
リスナースレッドが受けたリクエストを空いているワーカースレッドにわたす。
https://gyazo.com/0fe97d7d963d95620103a8cb945bc464
event
eventはworkerと同じような動作をするが、
Keep aliveという待ち状態になった場合、ワーカースレッドが枯渇してしまう。
そこで、必要のなくなったkeep aliveのワーカースレッド上での処理を、
リスナースレッドに返す事によって、枯渇状態にならないように立ち回る。
リスナースレッドに帰った後、次のイベントが来るまで待ち、再びワーカースレッドに渡す。
CentOS8ではデフォルトでeventに変更された。
つまり、デフォルトでは「mod_php」が利用できなくなったため、PHP-FPMを利用するようになった。
NginxでもPHP-FPMが利用されており、時代の変化なのかもしれない。
PHP-FPMに転送するモジュールとして「mod_proxy_fcgi」が用意されている。