PHP APCuをインストールしてWordPressのobject-cache.phpを配置
PHPのAPC, APCu, OPcacheに関しての知識を整理したときの覚書。
Gemini 3 Pro Previewと対話
環境: FreeBSD 14.3-RELEASE-p7, PHP 8.3.26, WordPress 6.9.0
1. APCuとは?
APCu は、PHPで動くインメモリの key-value ストア。
APCu(APC User Cache) は APC(Alternative PHP Cache)からOPcach機能を除いたもの。
参考: PHP: はじめに - Manual
APCからAPCuになるまでの経緯
- PHP 4.x 〜 PHP 5.4: APCがOpcode Cache(コードのキャッシュ)とUser Cache(データのキャッシュ)の両方の機能を担う。
- PHP 5.5: 2013年にコードのキャッシュ(Opcode Cache)はPHP本体に標準で組み込まれる。
- PHP 5.5以降 : APCから不要になったOpcode Cache機能を削除し、User Cache機能(データ保存)だけを切り出して軽量化・最新化したAPCuへ。
サーバーをクラスター構成で運用している場合は、ValkeyやRedisを利用する。
ValkeyやRedisを使うよりAPCuの方が通信のオーバーヘッドがないので圧倒的に高速。
2. APCuとWordPressの関係
WP_Object_CacheとWP Transients APIの関係。
- WP_Object_Cache: ページ生成中の一時的なデータ保持。
スレッドメモリに保存しページ表示後に破棄される。
APCuを導入すると共有メモリに保存しページ表示後に破棄されず再利用可能。 - WP Transients API: 有効期限がある長期間のデータ保持。
データベース(wp_options)に保存。
APCuを導入するとWP_Object_Cache経由でデータ取得保存するようになる。
WordPressはwp-includes/load.php:wp_start_object_cache()でobject-cache.phpを読み込んでいる。
3. APCuのインストール。
pkg経由でインストール。
# pkg search php83-pecl
# pkg install php83-pecl-APCu
読み込まれるiniファイルを確認して編集する。
# php --ini
# vim /usr/local/etc/php/ext-20-apcu.ini
extension=apcu.so; ----------------------------------------------------------------------; APCu (APC User Cache) 設定; ----------------------------------------------------------------------; APCuを有効にするかどうか; 1 = 有効 (デフォルト) / 0 = 無効apc.enabled=1; ----------------------------------------------------------------------; メモリ設定 (最重要); ----------------------------------------------------------------------; キャッシュに割り当てる共有メモリのサイズ; デフォルトは32Mですが、WordPressでは不足しがちです。; サーバーのメモリに余裕があれば 64M または 128M を推奨します。; (M = メガバイト, G = ギガバイト)apc.shm_size=256M; ----------------------------------------------------------------------; 有効期限 (TTL) 設定; ----------------------------------------------------------------------; キャッシュエントリの有効期限(秒); 0 にすると「明示的に消されるまで」あるいは「メモリが溢れるまで」永続します。; WordPressのAPCuプラグイン側で制御するため、基本は 0 でOKです。apc.ttl=0; ガベージコレクション(掃除)の猶予時間(秒); キャッシュがいっぱいで古いデータを消す際、この秒数以上アクセスがないデータを消します。; デフォルト: 3600 (1時間)apc.gc_ttl=3600; ----------------------------------------------------------------------; 高度な設定・トラブルシューティング; ----------------------------------------------------------------------; PHPのCLI(コマンドライン)版でAPCuを有効にするか; 0 = 無効 (推奨: 不要なトラブルを避けるため); 1 = 有効 (WP-CLI等でキャッシュ操作をしたい場合など); ※CLIとWebサーバーはメモリを共有しないため、CLIで有効にしてもWeb側は速くなりません。apc.enable_cli=0; スクリプトごとのキャッシュ実行時間の制限(秒); この時間を超えてキャッシュ操作をした場合、強制終了せずエラーを返します。; デフォルト: 0 (無制限)apc.use_request_time=0
php-fpmを再起動。
# php-fpm -t
# service php_fpm restart
確認。
# php -i | grep apc
4. APCu Manager プラグインのインストール
object-cache.phpだけを設置するか迷ったけど、APCu Manager プラグインをインストールしてみた。
# cd /path/to/wordpress/
# wp plugin install apcu-manager
管理画面でAPCu Managerを有効化する。
wp-contentは書き込み不可なので、探してコピーする。
# find ./wp-content/plugins/apcu-manager/ -name "object-cache.php"
# cp ./wp-content/plugins/apcu-manager/assets/object-cache.php wp-content/
APCu Manager プラグインの管理画面(WP CLIページ)でPHPエラーが出るのでやっぱりアンインストールする。
# wp plugin uninstall apcu-manager
wp-content/object-cache.phpはアンインストールと同時に削除された。
5. object-cache.phpを配置
GitHubからAPCuに対応したobject-cache.phpを探してwp-contentディレクトリに配置する。
参考: l3rady/object-cache-apcu
WordPressの管理画面のツール → サイトヘルス → テスト通過 → 「永続オブジェクトキャッシュを使用中です」と表示されれば有効になっている。
6. WP_APCU_KEY_SALTが必要?
下記エラーが発生してページが表示されなくなった。
[22-Jan-2026 00:01:08 UTC] PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 4295229440 bytes) in /home/httpd/hoge/wordpress/wp-includes/theme.php on line 325
最近の変更はobject-cache.phpを追加したことだったので、Gemini先生に聞いてみると、「マルチサイトのキー重複の可能性大」ということで、object-cache.phpのソースコードを読んでWP_APCU_KEY_SALTを設定してみた。
# vim wp-config.php
/*** APCu Object Cache Configuration** Generates a unique key based on the file path to prevent cache collisions* between multiple WordPress installations on the same server.*/define( 'WP_APCU_KEY_SALT', md5( __FILE__ ) );
だけど、WP_Object_Cacheの__constructで
$this->_absPath = md5(ABSPATH);
を行っているので、絶対パスが違えばキャッシュキーも違うはず。。。
日本語バージョンで更新。
# vim wp-config.php
/*** APCu Object Cache Configuration** object-cache.php の _key() メソッドにて、キャッシュキーの接頭辞として使用されます。* プラグイン側でインストールパス(md5(ABSPATH))による自動識別も行われますが、* サイト間の衝突をより確実に防ぐため、念のため明示的に一意な値を設定しています。*/define( 'WP_APCU_KEY_SALT', md5( __FILE__ ) );
一応これで様子を見る。