/etc/php-fpm.d/www.conf の末尾を見ると、以下の設定がコメントアウトされている場合があります。
;php_value[opcache.file_cache] = /var/lib/php/opcache
これは OPCache の「ファイルキャッシュ」機能に関する設定です。
通常 OPCache は共有メモリ上にコンパイル済みのオペコードを保持しますが、 この設定を有効にすることで、キャッシュデータをディスク上にも保存できるようになります。
ここでは OPCache のファイルキャッシュについて整理しておきます。
OPCache のファイルキャッシュとは
opcache.file_cache は、PHP スクリプトのコンパイル結果(オペコード)を
ディスク上に保存するためのディレクトリを指定する設定です。
通常の OPCache は、
- PHP-FPM 起動時に共有メモリを確保し
- 初回リクエスト時にスクリプトをコンパイルして
- その結果をメモリ上にキャッシュします
しかし PHP-FPM の再起動やサーバーの再起動が発生すると、 このメモリ上のキャッシュはすべて失われます。
opcache.file_cache を有効にすると、
- コンパイル済みのオペコードがディスクに保存され
- 再起動後にそのキャッシュを再利用できる
ようになります。
利点
再起動後のウォームアップ時間の短縮
PHP-FPM の再起動直後は OPCache が空の状態になるため、 Laravel のようにファイル数の多いアプリケーションでは、初回アクセス時に大量のコンパイル処理が発生します。
これがいわゆる「ウォームアップ時間」です。
ファイルキャッシュを有効にすると、 再起動後でもディスク上のキャッシュを再利用できるため、 ウォームアップ時間の短縮が期待できます。
OPCache 再起動の影響緩和
前回の記事で触れた通り、OPCache はフラグメンテーションの蓄積によって 再起動(restart)が発生することがあります。
この際、
- メモリキャッシュはすべて破棄されますが
- ファイルキャッシュが存在する場合は 再度コンパイルを行わずにキャッシュを復元できます
注意点
ディスク I/O の発生
ファイルキャッシュはディスクアクセスを伴うため、
- NVMe などの高速ストレージ環境では問題になりにくい一方
- IOPS が低い環境ではパフォーマンス低下の要因になる可能性があります
特にリクエスト数の多いサーバーでは注意が必要です。
ディレクトリの権限設定
指定したディレクトリは PHP-FPM プロセスが書き込み可能である必要があります。
例:
chown nginx:nginx /var/lib/php/opcache
chmod 750 /var/lib/php/opcache
関連する設定
opcache.file_cache_only
メモリキャッシュを使用せず、ディスクキャッシュのみを利用する場合に設定します。
php_value[opcache.file_cache_only] = 1
opcache.file_cache_consistency_checks
キャッシュされたファイルの整合性チェックを行うかどうかを指定します。
php_value[opcache.file_cache_consistency_checks] = 1
まとめ
opcache.file_cache は、PHP スクリプトのコンパイル済みコードをディスク上にキャッシュすることで、
- PHP-FPM 再起動後のウォームアップ時間の短縮
- OPCache 再起動時のパフォーマンス劣化の緩和
といった効果が期待できる設定です。
再起動が発生する可能性のある本番環境では、 有効化を検討する価値のあるオプションと言えます。
補足: ファイルキャッシュの内容を見る方法
cachetool を使ってみることができます。
一覧
# cachetool opcache:status:scripts
| Hits | Memory | Filename
| 2,172 | 1.55 KiB | /var/www/example/app/vendor/laravel/framework/....php
| 762 | 22.47 KiB | /var/www/example/site/wp-content/plugins/....php
Hitsの大きい順に上位20件
# cachetool opcache:status:scripts | sed 's/,//g' | sort -t'|' -k2 -n -r | head -20
補足: cachetool でファイルキャッシュをクリアする方法
検証環境で少しハマったので、手順をメモとして残しておきます。
ファイルキャッシュを有効化
# vi /etc/php-fpm.d/www.conf
php_value[opcache.file_cache] = /var/lib/php/opcache
# service php-fpm restart
しばしサイトアクセス
# ls -al /var/lib/php/opcache
total 0
drwxrwx--- 3 root apache 46 Dec 7 04:53 .
drwxr-xr-x 6 root root 68 Sep 4 01:36 ..
drwx------ 3 apache apache 18 Dec 7 04:53 8879d099d80daa65af95ffbeea78f52a
ファイルキャッシュができている
ファイルキャッシュのリセットを試す
# cachetool opcache:reset:file-cache
Are you sure you want to delete the contents of /var/lib/php/opcache? [no] yes
In FastCGI.php line 143:
FastCGI error: Stream got blocked, or terminated. (127.0.0.1:9000)
In Socket.php line 564:
Stream got blocked, or terminated.
エラーになった
リスニングソケット確認
# cat /etc/php-fpm.d/www.conf | grep "listen"
listen = 127.0.0.1:9000
オプションでリスニングソケットを指定すると
# cachetool --fcgi=127.0.0.1:9000 opcache:reset:file-cache
Are you sure you want to delete the contents of /var/lib/php/opcache? [no] yes
Deleted 361 files.
成功した