まえがき
PHPのパフォーマンスを向上させるための重要なツールの一つにOPcacheがあります。
OPcacheは、コンパイル済みのPHPスクリプトのバイトコードをメモリにキャッシュすることで、スクリプトの再実行時にコンパイルを省略し、実行速度を向上させます。
この記事では、Dockerを使用してPHPのOPcacheを有効化する方法を紹介します。
「そもそもOPCacheって何なの?」という方はこちらの記事 をご一読ください。
ステップ 1: Dockerfileの作成
Dockerfileを作成してPHP-FPMとOPcacheをセットアップします。
また、カスタムのphp.ini設定を適用するためのファイルも準備します。
FROM php:8.3-fpm
# OPcacheを有効にする
RUN docker-php-ext-enable opcache
ステップ 2: OPcacheの設定ファイルを作成
custom-php.iniには、OPcacheの設定を含めます。例えば下記のように設定します。
[opcache]
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.fast_shutdown=1
OPcacheの設定オプションの解説
custom-php.iniで設定した各項目の詳細について解説します。
基本設定
opcache.enable
1に設定するとOPcacheが有効になります。0に設定すると無効になります。
opcache.memory_consumption
- OPcacheが使用するメモリの最大量をメガバイト単位で指定します。
opcache.interned_strings_buffer
- PHPが内部的に使用する文字列のためのメモリ領域のサイズをメガバイト単位で指定します。
パフォーマンス設定
opcache.max_accelerated_files
- キャッシュできるPHPファイルの最大数を指定します。
opcache.validate_timestamps
1に設定すると、PHPファイルが変更されたかどうかをチェックします。(開発環境では基本的にこちらを使用します)0に設定すると、変更チェックを行わず、パフォーマンスが向上します。(本番環境では基本的にこちらを使用します)
opcache.revalidate_freq
opcache.validate_timestamps=1の場合、PHPファイルの変更をチェックする頻度を秒単位で指定します。opcache.revalidate_freq=60の場合、60秒ごとに更新することになります。
高度な設定
- opcache.fast_shutdown
1に設定すると、スクリプトの実行終了時のメモリ解放処理を最適化します。
これらの設定を適切に調整することで、アプリケーションのパフォーマンスを最適化し、エンドユーザーにより良い体験を提供することが可能になります。
ステップ 3: Nginxの設定
Nginxの設定ファイルdefault.confを作成し、PHPのリクエストをPHP-FPMに転送するように設定します。
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
ステップ 4: Docker Composeの設定
docker-compose.ymlファイルを作成して、NginxとPHP-FPMのコンテナを連携させます。
version: '3'
services:
nginx:
image: nginx:latest
container_name: nginx
ports:
- "8080:80"
volumes:
- ./default.conf:/etc/nginx/conf.d/default.conf
- ./html:/var/www/html
depends_on:
- php-fpm
networks:
- app-network
php-fpm:
build:
context: .
dockerfile: php-fpm.Dockerfile
container_name: php-fpm
volumes:
- ./html:/var/www/html
- ./custom-php.ini:/usr/local/etc/php/conf.d/custom-php.ini
networks:
- app-network
networks:
app-network:
driver: bridge
この設定では、htmlディレクトリ内のファイルがNginxとPHP-FPMの両方で共有されます。
ステップ 5: デモ用PHPスクリプトの準備
このスクリプトは、opcache_get_status()関数を使用してOPcacheの現在の設定と状態を取得し、それを整形して表示します。
OPcacheが有効であれば、キャッシュされているスクリプトの情報やキャッシュのヒット率など、詳細な情報を確認することができます。
check.phpスクリプトはhtmlディレクトリに配置します。
<?php
// OPcacheが有効かどうかを確認
if (function_exists('opcache_get_status')) {
$opcacheStatus = opcache_get_status(false);
if ($opcacheStatus) {
echo "<h1>OPcacheの状態</h1>";
echo "<p>OPcacheが有効になっています。</p>";
echo "<pre>";
print_r($opcacheStatus);
echo "</pre>";
} else {
echo "<p>OPcacheの状態を取得できません。OPcacheが有効になっていることを確認してください。</p>";
}
} else {
echo "<p>現在のPHPインストールではOPcacheが有効になっていません。</p>";
}
ステップ 6: 環境のビルドと起動
ここまでのステップでファイル構成は下記のようになっています。
$ tree
.
├── custom-php.ini
├── default.conf
├── docker-compose.yml
├── html
│ └── check.php
└── php-fpm.Dockerfile
以下のコマンドを実行して、環境をビルドし、起動します。
docker-compose up -d
ステップ 7: テストの実行
ブラウザからhttp://localhost:8080/check.php
にアクセスします。
ブラウザに下記内容が表示されれば問題なく動作しています。
OPcacheの状態
OPcacheが有効になっています。
Array
(
[opcache_enabled] => 1
[cache_full] =>
[restart_pending] =>
[restart_in_progress] =>
[memory_usage] => Array
(
[used_memory] => 9169096
[free_memory] => 125048632
[wasted_memory] => 0
[current_wasted_percentage] => 0
)
[interned_strings_usage] => Array
(
[buffer_size] => 8388608
[used_memory] => 2363368
[free_memory] => 6025240
[number_of_strings] => 5629
)
[opcache_statistics] => Array
(
[num_cached_scripts] => 1
[num_cached_keys] => 1
[max_cached_keys] => 16229
[hits] => 1
[start_time] => 1737270194
[last_restart_time] => 0
[oom_restarts] => 0
[hash_restarts] => 0
[manual_restarts] => 0
[misses] => 1
[blacklist_misses] => 0
[blacklist_miss_ratio] => 0
[opcache_hit_rate] => 50
)
[jit] => Array
(
[enabled] =>
[on] =>
[kind] => 5
[opt_level] => 4
[opt_flags] => 6
[buffer_size] => 0
[buffer_free] => 0
)
)
ステップ 8: custom-php.iniを変更してみよう
opcacheが有効になっていることが確認できたので、今度はcustom-php.iniを変更してopcacheを無効にしてみましょう。
下記のようにopcache.enableを0に設定するだけです。
[opcache]
opcache.enable=0
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.fast_shutdown=1
custom-php.iniを変更したら下記コマンドで再実行して変更を反映させます。
$ docker-compose restart php-fpm
下記だとダウンタイムなしで、設定ファイルを読み込むことができます。
$ docker kill --signal=USR2 php-fpm
上記コマンドについて簡単に解説すると、killコマンドはプロセスを終了させるだけでなく、シグナルを送ることによって様々な動作を実行させることができます。
USR2はユーザー定義シグナルと呼ばれるもので、アプリケーションによって動作が異なります。php-fpmではgraceful reload of all workers + reload of fpm conf/binaryという動作になり、
日本語訳では「全てのワーカープロセスを優雅に再起動(現在のリクエストが完了するまで待つ)し、FPM設定ファイルやバイナリを再読み込みする。」となります。
本番環境で動作している際に上記シグナルを送ることによってダウンタイム無しで設定ファイルの再読み込みができます。
ちなみにdocker killはコンテナに対してkillコマンドを実行しており、実際にコンテナに入って実行する際は下記のコマンドになります。
$ docker exec -it php-fpm bash
$ kill -USR2 1
こちらでも同様に設定ファイルの再読み込みが可能です。
反映完了後、ブラウザでhttp://localhost:8080/check.php に再度アクセスすると下記の出力になります。
OPcacheの状態を取得できません。OPcacheが有効になっていることを確認してください。
ちゃんと設定が反映されていますね。
これで設定ファイルを変更し、すぐに動作を確認できる状態になりました。ぜひ、さまざまな変更を試して動作を確認してみてください。
opcache-guiをインストールする
ここまででopcacheの有効化に関して解説は終わりですが、opcacheを使っていると、今どのくらいのメモリを使用しているのか確認したい時があります。
そういった場合にopcache-guiをインストールしておくととても便利です。
opcache-guiは、PHPのOPcacheの状態を視覚的に確認できるウェブインターフェースです。opcache-guiを使用すると、キャッシュの状態やパフォーマンス、設定などを簡単に確認できます。
opcache-guiの主な機能
キャッシュされたスクリプトの一覧表示
どのPHPファイルがOPcacheによってキャッシュされているかを確認できます。
キャッシュの使用状況
使用中のメモリ量、キャッシュされたスクリプトの数、キャッシュヒット率(キャッシュが効いている度合い)など、キャッシュの効率を示す指標を確認できます。
キャッシュの設定値
OPcacheの設定値を確認できます。
これには、メモリ消費量の上限やキャッシュするスクリプトの最大数などが含まれます。
キャッシュのクリア
ウェブインターフェースから直接、キャッシュをクリアすることができます。
これは、キャッシュされたデータをリセットしたい場合に便利です。
opcache-guiの利用方法
GitHub
からindex.phpファイルをダウンロードし、ウェブサーバーにアップロードします。その後、ブラウザからそのファイルにアクセスすることで、opcache-guiを使用できます。
具体的には先ほど作成したhtmlフォルダにダウンロードしたindex.phpを配置するだけで完了です。
$ tree
.
├── custom-php.ini
├── default.conf
├── docker-compose.yml
├── html
│ ├── check.php
│ └── index.php
└── php-fpm.Dockerfile
ブラウザからhttp://localhost:8080/index.php
にアクセスすると下記画面が表示されます。
もしThe Zend OPcache extension is installed but not activeと表示されたらopcache.enable=0となっているはずなのでopcache.enable=1に設定後、設定ファイルを再読み込みしてからもう一度試してください。
まとめ
この記事では、Dockerを活用してPHPのOPcacheを設定し、その効果を検証する方法をステップバイステップで解説しました。OPcacheはPHPスクリプトの実行速度を大幅に向上させることができる強力なツールであり、コンパイル済みのバイトコードをメモリにキャッシュすることで、スクリプトの再実行時のコンパイル時間を削減します。
このプロセスを通じて、アプリケーションのパフォーマンスを最適化し、エンドユーザーによりスムーズな体験を提供することが可能になります。