PHP-FPM:パフォーマンスを最大化するための設定とチューニング
PHP-FPM (FastCGI Process Manager) は、高負荷のウェブサイトにおいて、PHPアプリケーションのパフォーマンスと安定性を向上させるための重要なツールです。本記事では、PHP-FPMのアーキテクチャ、設定、チューニングについて詳しく解説し、パフォーマンスを最大限に引き出すための具体的な方法を提供します。
1. PHP-FPMの基礎
1.1 PHP-FPMとは
PHP-FPMは、PHPアプリケーションをFastCGIプロトコルで処理するためのプロセス管理ツールです。従来のCGI (Common Gateway Interface) に比べて、PHPスクリプトの実行速度が大幅に向上し、リソース効率も改善されます。PHP-FPMは、ウェブサーバー(例えば、NginxやApache)とPHPアプリケーションの間で仲介役を果たし、リクエストを効率的に処理します。
1.2 なぜPHP-FPMが必要なのか
ウェブサイトのトラフィックが増加すると、PHPアプリケーションのパフォーマンスがボトルネックになることがあります。CGIでは、リクエストごとにPHPインタプリタを起動するため、リソース消費が大きく、応答速度が低下します。PHP-FPMは、PHPインタプリタを事前に起動しておき、リクエストを待機させることで、起動オーバーヘッドを削減し、高速な処理を実現します。
1.3 PHP-FPMのアーキテクチャ
PHP-FPMは、以下の主要なコンポーネントで構成されています。
- マスタープロセス (Master Process): PHP-FPM全体の管理を行い、設定ファイルの読み込み、ワーカプロセスの起動・停止などを担当します。
- ワーカプロセス (Worker Process): 実際にPHPスクリプトを実行するプロセスです。複数のワーカプロセスが並行して動作し、リクエストを処理します。
- リスナー (Listener): ウェブサーバーからのリクエストを待ち受けるソケットです。通常、TCPポートまたはUnixドメインソケットを使用します。
- プロセスプール (Process Pool): ワーカプロセスのグループです。複数のプールを定義することで、異なるPHP設定やリソース制限を適用できます。
2. PHP-FPMの設定ファイル
PHP-FPMの設定ファイルは、通常 /etc/php/X.X/fpm/php-fpm.conf
(X.XはPHPのバージョン) と /etc/php/X.X/fpm/pool.d/www.conf
にあります。これらのファイルを適切に設定することで、PHP-FPMのパフォーマンスを最適化できます。
2.1 グローバル設定 (php-fpm.conf)
/etc/php/X.X/fpm/php-fpm.conf
ファイルには、PHP-FPM全体の動作に関する設定が含まれています。
ini
[global]
pid = /run/php/phpX.X-fpm.pid
error_log = /var/log/phpX.X-fpm.log
log_level = warning
daemonize = yes
process.max = 128
emergency_restart_threshold = 10
emergency_restart_interval = 1m
process_control_timeout = 10s
- pid: PHP-FPMのプロセスIDを記録するファイルのパス。
- error_log: エラーログの出力先。
- log_level: ログのレベル(
debug
,notice
,warning
,error
,critical
など)。 - daemonize: PHP-FPMをデーモンとして実行するかどうか。
- process.max: PHP-FPMが起動できるワーカプロセスの最大数。
- emergency_restart_threshold: 指定された時間内にワーカプロセスが異常終了した場合に、PHP-FPMを再起動する回数。
- emergency_restart_interval:
emergency_restart_threshold
の監視期間。 - process_control_timeout: ワーカプロセスの起動・停止にかかるタイムアウト時間。
2.2 プール設定 (www.conf)
/etc/php/X.X/fpm/pool.d/www.conf
ファイルには、ワーカプロセスのプールに関する設定が含まれています。
ini
[www]
user = www-data
group = www-data
listen = /run/php/phpX.X-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
request_terminate_timeout = 120s
request_slowlog_timeout = 10s
slowlog = /var/log/phpX.X-fpm.log.slow
php_admin_value[error_log] = /var/log/fpm-php.www.log
php_admin_flag[log_errors] = on
- user: ワーカプロセスを実行するユーザー。
- group: ワーカプロセスを実行するグループ。
- listen: ウェブサーバーからのリクエストを待ち受けるアドレス(TCPポートまたはUnixドメインソケット)。
- listen.owner: ソケットファイルのオーナー。
- listen.group: ソケットファイルのグループ。
- listen.mode: ソケットファイルのパーミッション。
- pm: プロセスマネージャーの動作モード(
static
,dynamic
,ondemand
)。 - pm.max_children: ワーカプロセスの最大数。
- pm.start_servers: PHP-FPM起動時に起動するワーカプロセスの数。
- pm.min_spare_servers: アイドル状態を維持するワーカプロセスの最小数。
- pm.max_spare_servers: アイドル状態を維持するワーカプロセスの最大数。
- pm.max_requests: ワーカプロセスが処理するリクエストの最大数。この数に達すると、プロセスは再起動されます。
- request_terminate_timeout: スクリプトの実行時間制限(秒)。この時間を超えると、プロセスは強制終了されます。
- request_slowlog_timeout: スクリプトの実行時間がこの値を超えると、スローログに記録されます。
- slowlog: スローログの出力先。
- php_admin_value[error_log]: このプールでのエラーログの出力先。
- php_admin_flag[log_errors]: エラーログの記録を有効にするかどうか。
3. パフォーマンスチューニング
PHP-FPMのパフォーマンスを最大化するためには、以下の要素を考慮して設定を調整する必要があります。
3.1 プロセスマネージャーの設定 (pm)
PHP-FPMのプロセスマネージャーには、static
, dynamic
, ondemand
の3つのモードがあります。
-
static: 起動時に指定された数のワーカプロセスを常に維持します。リクエストの増減に関わらず、常に一定のリソースを消費します。
- 利点: リクエストの応答速度が安定している。
- 欠点: リソース消費が大きい。
- 推奨: 常に高いトラフィックが予想される場合。
-
dynamic: リクエストの負荷に応じて、ワーカプロセスの数を自動的に調整します。アイドル状態のプロセスを減らし、リソースを節約します。
- 利点: リソース効率が良い。
- 欠点: 負荷の変動が大きい場合、応答速度が不安定になることがある。
- 推奨: 通常のウェブサイトやAPIサーバー。
-
ondemand: リクエストがあった場合にのみワーカプロセスを起動します。アイドル状態のプロセスを完全に停止し、リソースを最大限に節約します。
- 利点: リソース消費が非常に少ない。
- 欠点: 初回リクエストの応答速度が遅くなる。
- 推奨: 低トラフィックのウェブサイトや、リソースが限られている環境。
3.2 ワーカプロセスの数 (pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers)
ワーカプロセスの数は、PHP-FPMのパフォーマンスに大きな影響を与えます。適切な数を設定することで、リクエストの処理能力を向上させることができます。
- pm.max_children: ワーカプロセスの最大数。この数を大きくすると、より多くのリクエストを並行して処理できますが、メモリ消費も増加します。
- pm.start_servers: PHP-FPM起動時に起動するワーカプロセスの数。
- pm.min_spare_servers: アイドル状態を維持するワーカプロセスの最小数。リクエストの急増に対応するために、常に一定数のプロセスを待機させておく必要があります。
- pm.max_spare_servers: アイドル状態を維持するワーカプロセスの最大数。リソースの無駄遣いを防ぐために、適切な上限を設定する必要があります。
最適な数の決定:
- メモリの測定: 各ワーカプロセスが消費するメモリ量を測定します。
top
コマンドやps
コマンドを使用できます。 - 総メモリの計算: サーバーの総メモリ量から、OSや他のアプリケーションが使用するメモリ量を差し引きます。
-
ワーカプロセスの数の算出: 以下の式でワーカプロセスの最大数を計算します。
pm.max_children = (総メモリ量 - OSが使用するメモリ量) / ワーカプロセスあたりのメモリ消費量
4. テスト: 実際に負荷テストを行い、応答速度やエラー率を監視しながら、pm.max_children
の値を調整します。
pm.start_servers
, pm.min_spare_servers
, pm.max_spare_servers
の値は、pm
モードに応じて調整します。dynamic
モードの場合、pm.min_spare_servers
は低い値を設定し、pm.max_spare_servers
は高い値を設定することで、リソース効率を向上させることができます。
3.3 リクエストのタイムアウト (request_terminate_timeout)
request_terminate_timeout
は、PHPスクリプトの実行時間制限を設定します。この時間を超えると、PHP-FPMはプロセスを強制終了します。
- 適切な値: スクリプトの平均実行時間よりも少し長い値を設定します。長すぎるタイムアウトは、ハングしたプロセスがリソースを消費し続ける原因になります。短すぎるタイムアウトは、正常なスクリプトが途中で終了してしまう可能性があります。
- スローログの活用:
request_slowlog_timeout
とslowlog
を設定して、実行時間が長いスクリプトを特定し、最適化します。
3.4 リクエストの最大数 (pm.max_requests)
pm.max_requests
は、ワーカプロセスが処理するリクエストの最大数を設定します。この数に達すると、プロセスは再起動されます。
- 目的: メモリリークやその他のリソースリークを回避するために、定期的にプロセスを再起動します。
- 適切な値: プロセスの安定性やリソース消費を考慮して、適切な値を設定します。一般的には、数百から数千程度が推奨されます。
- メモリリークの監視: 定期的にメモリ使用量を監視し、
pm.max_requests
の値を調整します。
3.5 OPcacheの設定
OPcacheは、PHPスクリプトをコンパイルした結果をキャッシュする機能です。OPcacheを有効にすることで、PHPスクリプトの実行速度が大幅に向上します。
設定方法:
/etc/php/X.X/fpm/php.ini
ファイルに以下の設定を追加します。
ini
[opcache]
zend_extension=opcache.so
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=2
opcache.use_cwd=1
opcache.validate_timestamps=1
opcache.save_comments=1
opcache.fast_shutdown=1
- opcache.enable: OPcacheを有効にするかどうか。
- opcache.memory_consumption: OPcacheが使用するメモリ量(MB)。
- opcache.interned_strings_buffer: 内部文字列のキャッシュに使用するメモリ量(MB)。
- opcache.max_accelerated_files: キャッシュするファイルの最大数。
- opcache.revalidate_freq: キャッシュを検証する頻度(秒)。
- opcache.use_cwd: 現在のディレクトリをキャッシュキーの一部として使用するかどうか。
- opcache.validate_timestamps: ファイルのタイムスタンプを検証して、キャッシュを更新するかどうか。
- opcache.save_comments: コメントを保存するかどうか。
- opcache.fast_shutdown: 高速シャットダウンを有効にするかどうか。
チューニング:
- メモリの調整:
opcache.memory_consumption
の値を調整して、キャッシュヒット率を最大化します。 - ファイルの最大数の調整:
opcache.max_accelerated_files
の値を調整して、すべてのPHPファイルをキャッシュできるようにします。 - キャッシュの検証頻度の調整:
opcache.revalidate_freq
の値を調整して、キャッシュの鮮度を維持します。
3.6 ログの設定
適切なログ設定は、PHP-FPMの問題を特定し、パフォーマンスを改善するために重要です。
- error_log: エラーログの出力先を設定します。
- log_level: ログのレベルを設定します。開発環境では
debug
レベルを使用し、本番環境ではwarning
またはerror
レベルを使用します。 - slowlog: スローログの出力先を設定します。
- request_slowlog_timeout: スローログに記録するスクリプトの実行時間制限を設定します。
ログの分析:
- エラーログ: PHPスクリプトのエラーや警告を特定します。
- スローログ: 実行時間が長いスクリプトを特定し、最適化します。
- PHP-FPMのログ: PHP-FPM自体のエラーや警告を特定します。
3.7 その他のチューニングポイント
- データベースの最適化: データベースクエリの最適化、インデックスの活用、キャッシュの利用など。
- ネットワークの最適化: CDNの利用、HTTP/2の有効化、Keep-Aliveの設定など。
- コードの最適化: 不要な処理の削減、アルゴリズムの改善、キャッシュの利用など。
- ハードウェアのアップグレード: CPU、メモリ、ストレージなどのリソースを増強します。
4. ウェブサーバーとの連携
PHP-FPMは、NginxやApacheなどのウェブサーバーと連携して動作します。ウェブサーバーの設定を適切に行うことで、PHP-FPMのパフォーマンスを最大限に引き出すことができます。
4.1 Nginxの設定
NginxでPHP-FPMを使用する場合、以下の設定を行います。
“`nginx
server {
listen 80;
server_name example.com;
root /var/www/example.com;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/phpX.X-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
“`
- fastcgi_pass: PHP-FPMのリスナーアドレスを指定します。Unixドメインソケットを使用する場合は、
unix:/run/php/phpX.X-fpm.sock
を指定します。TCPポートを使用する場合は、127.0.0.1:9000
のように指定します。 - include snippets/fastcgi-php.conf: PHP-FPMとの連携に必要な設定が含まれています。
4.2 Apacheの設定
ApacheでPHP-FPMを使用する場合、以下の設定を行います。
“`apache
ServerName example.com
DocumentRoot /var/www/example.com
<Directory /var/www/example.com>
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
“`
- SetHandler “proxy:fcgi://127.0.0.1:9000”: PHP-FPMのリスナーアドレスを指定します。TCPポートを使用する場合は、
127.0.0.1:9000
のように指定します。Unixドメインソケットを使用する場合は、unix:/run/php/phpX.X-fpm.sock
のように指定します。
5. 負荷テストと監視
PHP-FPMのパフォーマンスを評価し、チューニングの効果を確認するために、負荷テストと監視を行うことが重要です。
5.1 負荷テストツール
- ApacheBench (ab): シンプルなHTTP負荷テストツール。
- Siege: 複数のURLに対して同時アクセスを行うことができる負荷テストツール。
- JMeter: 高度な機能を持つJava製の負荷テストツール。
- k6: JavaScriptで記述できる負荷テストツール。
5.2 監視ツール
- htop: プロセスのリソース使用状況をリアルタイムで監視するツール。
- netdata: システム全体のリソース使用状況を詳細に監視するツール。
- Prometheus: 時系列データベースとして、メトリクスを収集・監視するツール。
- Grafana: Prometheusなどのデータソースからグラフを作成し、可視化するツール。
監視するメトリクス:
- CPU使用率: PHP-FPMのCPU使用率を監視します。
- メモリ使用量: PHP-FPMのメモリ使用量を監視します。
- ディスクI/O: PHP-FPMのディスクI/Oを監視します。
- ネットワークトラフィック: PHP-FPMのネットワークトラフィックを監視します。
- リクエスト数: PHP-FPMが処理するリクエスト数を監視します。
- 応答時間: PHP-FPMの応答時間を監視します。
- エラー率: PHP-FPMのエラー率を監視します。
- ワーカプロセスの数: PHP-FPMのワーカプロセスの数を監視します。
6. まとめ
PHP-FPMは、PHPアプリケーションのパフォーマンスを向上させるための強力なツールです。適切な設定とチューニングを行うことで、リクエストの処理能力を最大化し、安定したウェブサイトを運用することができます。
本記事では、PHP-FPMのアーキテクチャ、設定ファイル、パフォーマンスチューニング、ウェブサーバーとの連携、負荷テストと監視について詳しく解説しました。これらの知識を活用して、PHP-FPMのパフォーマンスを最適化し、より高速で安定したウェブサイトを実現してください。
7. 付録:トラブルシューティング
PHP-FPMのトラブルシューティングについて、よくある問題とその解決策を以下に示します。
- PHP-FPMが起動しない: 設定ファイルのエラー、ポートの競合、権限の問題などが原因として考えられます。エラーログを確認し、問題を特定してください。
- PHPスクリプトの実行が遅い: データベースクエリの最適化、OPcacheの設定、コードの最適化などを行います。
- PHP-FPMがリクエストを処理できない: ワーカプロセスの数が不足している、リクエストのタイムアウトが短すぎるなどが原因として考えられます。
- PHP-FPMがメモリを大量に消費する: メモリリークが発生している可能性があります。
pm.max_requests
を設定して、定期的にプロセスを再起動してください。 - NginxまたはApacheとの連携がうまくいかない: 設定ファイルの誤り、ポートの競合、権限の問題などが原因として考えられます。
この記事が、読者の皆様のPHP-FPMのパフォーマンスチューニングの一助となれば幸いです。