FreeBSD14 + PHP8.3 + OPcache

PHP Opcacheをインストールしたときの覚書。

環境: FreeBSD 14.3-RELEASE-p2, Nginx 1.28.0, PHP 8.3.23


1. PHP OPcacheとは?

OPcacheは、PHPスクリプトを一度コンパイルした結果をメモリにキャッシュすることで、次からのリクエストを高速に処理する仕組み。

OPcacheはPHP 5.5(2023年6月リリース)からバンドル。

CentOS Stremのyumやdnfでインストールするとデフォルトで有効になる。
FreeBSDではpkgでインストールしてもデフォルトで有効にならない。

OPcacheが有効か確認するコマンド。
# php -i | grep opcache


各レイヤーごとにキャッシュ機能を導入することで相乗効果が期待できる。

  1. Web Serverのキャッシュ: Nginx fastcgi_cache
  2. PHPのキャッシュ: OPcache
  3. OSのキャッシュ: ZFS

ただしメモリを消費するので正しく設定しないと逆効果。


OPcacheとJIT

JIT(Just-In-Time)コンパイラはPHP8から導入された機能で、OPcacheを高速化のための拡張機能。
JITは、アプリケーションの実行を監視し、頻繁に使われるコード(ホットコード)を特定し、ネイティブなマシンコードに変換し、専用のメモリ領域(JITバッファ)にキャッシュする。

JITはOPcacheが前提の機能。
Zend VMというインタープリタを挟まないため、特にCPU負荷の高い処理が劇的に高速化される。

WordPressだと頻繁に呼び出されるアクションとフィルターフックが高速化され、体感速度が向上する。


2.OPcacheをインストール。

まずはインストールされているか確認。
# php -i | grep opcache

pkg でインストール。
# pkg install php83-opcache

php --versionを打つとOPcacheがインストールされているか確認できる。
# php --version

PHP 8.3.23 (cli) (built: Jul  5 2025 03:29:14) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.23, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.23, Copyright (c), by Zend Technologies

php infoでも確認。
# php -i | grep opcache

Additional .ini files parsed => /usr/local/etc/php/ext-10-opcache.ini,
opcache.blacklist_filename => no value => no value
opcache.dups_fix => Off => Off
opcache.enable => On => On
opcache.enable_cli => Off => Off
opcache.enable_file_override => Off => Off
opcache.error_log => no value => no value
opcache.file_cache => no value => no value
opcache.file_cache_consistency_checks => On => On
opcache.file_cache_only => Off => Off
opcache.file_update_protection => 2 => 2
opcache.force_restart_timeout => 180 => 180
opcache.huge_code_pages => Off => Off
opcache.interned_strings_buffer => 8 => 8
opcache.lockfile_path => /tmp => /tmp
opcache.log_verbosity_level => 1 => 1
opcache.max_accelerated_files => 10000 => 10000
opcache.max_file_size => 0 => 0
opcache.max_wasted_percentage => 5 => 5
opcache.memory_consumption => 128 => 128
opcache.opt_debug_level => 0 => 0
opcache.optimization_level => 0x7FFEBFFF => 0x7FFEBFFF
opcache.preferred_memory_model => no value => no value
opcache.preload => no value => no value
opcache.preload_user => no value => no value
opcache.protect_memory => Off => Off
opcache.record_warnings => Off => Off
opcache.restrict_api => no value => no value
opcache.revalidate_freq => 2 => 2
opcache.revalidate_path => Off => Off
opcache.save_comments => On => On
opcache.use_cwd => On => On
opcache.validate_permission => Off => Off
opcache.validate_root => Off => Off
opcache.validate_timestamps => On => On

php.iniは置き換わることがあるので、各エクステンションの設定は各iniファイルに記述する。
開発環境向けはvalidate_timestampsを有効にする。
# less /usr/local/etc/php/ext-10-opcache.ini

zend_extension=opcache.so

[opcache]
; OPcacheを有効にする
opcache.enable=1

; CLI版のPHPでも有効にする (Composerやcronジョブの実行が高速化)
opcache.enable_cli=1

; ファイルのタイムスタンプ(更新日時)をチェックして、
; 変更があった場合にキャッシュを更新するようにします。
; 本番環境ではパフォーマンスのために 0 (無効) にすることが多いです。
opcache.validate_timestamps=1

; タイムスタンプをチェックする頻度(秒)。
; 開発中は即時反映させたいので「0」に設定します。
; これにより、リクエスト毎にファイルの更新をチェックします。
; デフォルトは 2 (秒) なので、何もしないと最大2秒間は変更が反映されません。
opcache.revalidate_freq=0

php-fpmを再起動。
# service php_fpm restart

確認。
# php -i | grep opcache


3. 本番環境でのOpcache設定

Gemini 2.5 Proに下記条件を与えてOpcache設定を提案してもらった。

条件を追加しますので、OPcache設定を再考してください。
その他設定に必要な条件があれば教えてください。
・本番環境
・メモリ12GBの仮想マシン
・FreeBSD 14.3-RELEASE-p2
・nginx 1.28.0
・PHP 8.3.23
・WordPressで構築したホームページを運用するウェブサーバー

提案通りに設定。
# less /usr/local/etc/php/ext-10-opcache.ini

; OPcache拡張モジュールを有効化
zend_extension=opcache.so

[opcache]
; OPcacheを有効にする
opcache.enable=1

; CLI版のPHPでも有効にする (WP-CLIやcronジョブが高速化)
opcache.enable_cli=1

; --- パフォーマンス最優先の本番設定 ---

; ★最重要: ファイルのタイムスタンプチェックを無効化。本番環境でのパフォーマンスを最大化。
; ※注意: テーマやプラグインの更新後は、必ずphp-fpmのリロードが必要です。
opcache.validate_timestamps=0

; --- メモリ関連 (12GB VM / WordPress向け) ---

; OPcacheが使用する共有メモリ量(MB)。
; WordPressはファイル数が多いため、256MBは堅実な出発点です。
; ZFS ARCやDBとの共存を考え、過剰な割り当ては避けます。
opcache.memory_consumption=1536M

; PHP内部の文字列を保持するためのメモリ量(MB)。
; WordPressや多くのプラグインは文字列を多用するため、32MBを推奨。
opcache.interned_strings_buffer=32M

; キャッシュできるファイル数の上限。
; WordPressコア + テーマ + 多数のプラグインを想定し、多めに設定します。
; 20000あれば、ほとんどのサイトで不足することはありません。
opcache.max_accelerated_files=20000

; --- 互換性と安定性 (WordPress向け) ---

; ★重要: コメントをキャッシュに含める。
; WordPressはプラグインやテーマのヘッダー情報をファイルのコメントから読み取るため、これは必須です。
opcache.save_comments=1

; PHP 8.x のJIT(Just-In-Time)コンパイラを有効化。
; 'tracing'モードはWebアプリケーションのパフォーマンスと安定性のバランスが最も良い。
opcache.jit_buffer_size=128M
opcache.jit=tracing

; --- その他 ---

; メモリの浪費をチェックする頻度(秒)。デフォルトの60秒でOK。
opcache.revalidation_freq=60

テストして設定反映。本番環境はreloadする。
(restartは稼働中のプロセスを強制的にkillしてしまうから)
# php-fpm -t
# service php_fpm reload

確認。
# php -i | grep opcache

メモリの空き容量を確認。
# top

Opcacheのキャッシュをクリアするときはphp_fpmをreloadする。
# service php_fpm reload

PHP CLIは、そのプロセス内でのみOPcacheが機能し、プロセスが終了すればキャッシュも消えるので、OPcacheを手動でクリアするという操作は基本的に不要らしい。


4.opcache-guiのインストール

opcacheの状況を可視化するツールをインストール。
参考: amnuts/opcache-gui: A clean, effective and responsive interface for Zend OPcache

git cloneする。
# cd /home/httpd/tools/
# git clone https://github.com/amnuts/opcache-gui.git

Nginxの設定。
# less /usr/local/etc/nginx/conf.d/01_tools.conf

server {
    listen       80;
    listen       [::]:80;
    server_name  opcache-gui.hoge.co.jp;

    root    /home/httpd/tools/opcache-gui/;
    index index.php;
    charset utf-8;

    # Basic Authentication
    auth_basic    "Secret Area for hoge";
    auth_basic_user_file  "/home/httpd/tools/.htpasswd";

    # IP Limitation
    include conf.d/include/allow/webrec-office.inc;
    deny all;

    location ~* \.php$ {
        include conf.d/include/fastcgi_php.inc;
    }
}

phpMyAdminをインストールするときに設定したBasic認証とIP制限を流用している。

確認してnginx再読み込み。
# nginx -t
# service nginx reload

ブラウザでアクセスして確認。

opcache-guiの確認すべきポイント

  • Memory(右一番上の円グラフ):  グラフが100%に達しているのはメモリ不足を意味します。
    その場合はopcache.memory_consumption の値を増やします。
  • hit rate(右二番目の円グラフ):  99%以上で安定しているか。
     ヒット率が低い(例: 90%以下)、または常に大きく変動している。これはキャッシュが効率的に使われていない証拠。
  • keys(右三番目の円グラフ):  100%だとキャッシュできるファイル数の上限に達したことを意味します。
    その場合はopcache.max_accelerated_files の値を増やします。

最初opcache.memory_consumptionを512に設定していたけど、すぐ100%になったので1024に増やした。

体感速度がかなり向上した気がする。
opcache.memory_consumptionを環境に合わせて設定するのが重要。



▼ 関連記事