システムパフォーマンス入門

パフォーマンスに詳しいインフラに憧れて

ユーザ用ツール

サイト用ツール


· 最終更新: 2021/04/13 by kurihara


ApacheのMPM設定(preforkかworkerかevent比較)

mpmとは

  • mpm(Multi Processing Module)
  • 複数人のクライアントからのリクエストを並行処理するためのWebサーバの実装モデル

PHPを利用する方法

Apache(prefork MPM) + mod_php 従来の方法
Apache(event MPM) + php-fpm メモリ使用量を大きく減らす。
同時接続数増加時のパフォーマンス劣化も抑えられる

詳細は、PHPを利用する場合のWebサーバ比較(ApacheかNginxかLiteSpeedか)

利用しているMPMの確認

# httpd -V
[Tue Apr 13 23:40:31.103797 2021] [so:warn] [pid 8379:tid 140302715390080] AH01574: module status_module is already loaded, skipping
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::a00:27ff:fe15:777d. Set the 'ServerName' directive globally to suppress this message
Server version: Apache/2.4.6 (CentOS)
Server built:   Oct 19 2017 20:39:16
Server's Module Magic Number: 20120211:24
Server loaded:  APR 1.4.8, APR-UTIL 1.5.2
Compiled using: APR 1.4.8, APR-UTIL 1.5.2
Architecture:   64-bit
Server MPM:     event   ★
  threaded:     yes (fixed thread count)
    forked:     yes (variable process count)
Server compiled with....
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=256
 -D HTTPD_ROOT="/etc/httpd"
 -D SUEXEC_BIN="/usr/sbin/suexec"
 -D DEFAULT_PIDLOG="/run/httpd/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"


preforkとeventとworkerの比較

  • Apache2.2系では、preforkが利用される。Apache2.4系では、eventが使えます。
  • CentOS 8 の Apache は デフォルトで “event” が選択されていました。
  • CentOS 7 までの Apache は デフォルトで “prefork” が選択されていました。
  • スレッドセーフでないモジュールを使う場合は、preforkを利用する必要があります。
    スレッドセーフとは、そのコードを複数のスレッドが同時並行的に実行しても問題が発生しないこと。

prefork

マルチプロセス

  • プロセス数=同時接続数
  • pre(=前もって)forkしておくこと。
  • preforkは複数の子プロセスを起動する。そして、子プロセスは1つのスレッドを持つ。
  • 1つのプロセスが1つのコネクションをみる
  • preforkの方がスピード面でworkerに勝るが、メモリ使用効率が悪い。
  • 親プロセスを1つ持ち、クライアントからリクエストが来ると自分自身をコピーして子プロセスを起動(forkという)して、実際の通信は子プロセスが受け持つ。
  • あらかじめいくつかの子プロセスをforkしておき、forkの待ち時間をなくす方式をとるのが、preforkである。
  • forkされた子プロセス1つ1つが対応する通信を受け持つため、ある子プロセスが何らかの原因でフリーズしたとしても、他の子プロセスには影響を及ぼすことが無く通信を継続できる。
  • クライアントが多くなればなるほど子プロセスの数も増えるため、使用メモリ量やCPU負荷が比例的に増大していく。


event

マルチスレッド+非同期(nginx ライク)

  • KeepAlive問題を解決している。
KeepAlive問題
  • Keepaliveは、設定した時間受付を待つ。そして、受付を待っている間は、他のリクエストを受け付けてくれない。
  • KeepAliveTimeout(デフォルト:15秒)
event MPMの問題
  • スレッドを使用するモデルなので、mod_php などの非スレッドセーフなモジュールを利用する際には使用できません。


worker

マルチスレッド

  • 1つのスレッドが1つのコネクションを扱う。
  • 複数の子プロセスを起動し、さらにその子プロセスは複数のスレッドを持つ。
  • Apacheの子プロセス1つ1つがマルチスレッドで動作し、スレッド1つが1つのクライアントを受け持つ方式である。
  • 多くの子プロセスを起動せずに済むため、メモリの使用量も減らすことが出来る。
worker MPMの問題
  • マルチスレッドは安定して動作させるためにノウハウが必要
  • スレッドを使用するモデルなので、mod_php などの非スレッドセーフなモジュールを利用する際には使用できません。
  • PHPでは、workerモードの場合、「php-mbstring」や「php-mysql」などのPHP拡張機能が使えない。


利用しているMPMの確認方法

方法1: apachectl -V コマンドで確認

■パッケージからインストールした場合
# apachectl -V | grep 'Server MPM'

■ソースからインストールした場合
# /usr/local/apache/bin/apachectl -V | grep 'Server MPM'


Server MPM:     Prefork
または
Server MPM:     Worker

方法2:静的モジュールで確認

■パッケージからインストールした場合
# /usr/sbin/httpd -l

■ソースからインストールした場合
# /usr/local/apache2/bin/httpd -l

prefork.cがあるかevent.cがあるかで確認する。


MPMの変更方法

2.4系パッケージ

/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
か
LoadModule mpm_worker_module modules/mod_mpm_worker.so


2.2系パッケージ

「/etc/sysconfig/httpd」ファイルの「HTTPD=/usr/sbin/httpd.worker」の行をコメントアウトしてApacheを再起動する

HTTPD=/usr/sbin/httpd.worker


ソース

configure時のオプション
--with-mpm=prefork


MPMのパフォーマンス設定

eventのパフォーマンス設定

/etc/httpd/conf.modules.d/10-mpmevent.conf

## 2coreの場合
<IfModule mpm_event_module>
    ServerLimit              5
    StartServers             2   #core数
    MinSpareThreads          64   #StartServers × ThreadsPerChild (2 x 32)
    MaxSpareThreads          128
    ThreadLimit              5
    ThreadsPerChild          32
    MaxRequestWorkers        160    # ServerLimit × ThreadsPerChild (5 x 32)
    MaxConnectionsPerChild   1500
</IfModule>
## 2coreの場合
<IfModule mpm_event_module>  
    ServerLimit               8
    StartServers              2   #core数
    MinSpareThreads         128   #StartServers × ThreadsPerChild (2 x 64)
    MaxSpareThreads         256
    ThreadsPerChild          64
    MaxRequestWorkers       512   # ServerLimit × ThreadsPerChild (8 x 64)
    MaxConnectionsPerChild 1500
</IfModule>  
設定項目 説明
ServerLimit プロセス数の上限
StartServers サーバ起動時に作られるプロセスの数
Number of Cores
MinSpareThreads アイドルスレッドの下限の個数
サーバが忙しくなってアイドルスレッドが減少した時にこの数まで増やされます。
StartServers × ThreadsPerChild
ThreadsPerChildの倍数を指定
MaxSpareThreads アイドルスレッドの上限の個数
サーバが暇になってアイドルスレッドが増えた時にこの数まで減らされます。
ThreadLimit プロセスごとのワーカースレッドの上限
ThreadsPerChildよりも大きな値を指定する
ThreadsPerChild プロセス内に用意するワーカースレッドの数
MaxRequestWorkers 全プロセス合計のワーカースレッドの総数
応答できる同時リクエスト数。
PreforkのMaxClients。
ServerLimit × ThreadsPerChild
MaxConnectionsPerChild プロセスが指定した回数の接続を受け付けたらプロセスを終了します。
0を指定すると終了しなくなります。


preforkのパフォーマンス設定

<IfModule mpm_prefork_module>
        StartServers            256
        MinSpareServers         1
        MaxSpareServers         256
        ServerLimit             256
        MaxClients              256
        MaxRequestsPerChild     5000
        MaxMemFree              1024
</IfModule>

1プロセスあたりメモリーが4MBだと、1G使われます。

設定項目 説明
StartServers 起動時に生成される子サーバプロセスの数。
デフォルトは5。
MinSpareServers アイドル状態にいる子サーバプロセスの最小(希望)個数。
デフォルトは5
常にこの数のプロセスはアイドルでいてくださいね、という値。
MaxSpareServers アイドル状態にいる子サーバプロセスの最大(希望)個数。
デフォルトは10。
アイドル状態の子サーバプロセスの数がこの値をこえた時は小サーバプロセスを殺してくださいね、という値。
ServerLimit MaxClientsに指定可能な値の上限
MaxClientsより多い値ならなんでもよい
MaxClients 応答できる同時リクエスト数。
デフォルトは256。
MaxRequestsPerChild 個々の子サーバプロセスが扱うことのできるリクエストの総数。
子サーバプロセスが起動してからこの数だけリクエストを捌くとなくなる。
デフォルトは10000。
メモリリーク対策。
MaxMemFree この値を超えたメモリはOSに帰る





· 最終更新: 2021/04/13 by kurihara

ページ用ツール