そのまんま!

III. Alternative PHP Cache (APC)

導入

Alternative PHP Cache (APC) は、PHP の実行コードをキャッシュする仕組みで、 フリーかつオープンに使用できます。PHP の中間コードのキャッシュ・最適化を 行うためのフリーでオープン、かつ堅牢なフレームワークを提供するという 考えのもとに作られています。

インストール手順

この PECL 拡張 モジュールは PHP にバンドルされていません。

この PECL 拡張モジュールをインストールする方法は、 マニュアルの PECL 拡張モジュールのインストール という章にあります。 新規リリース・ダウンロード・ソースファイル・管理者情報・CHANGELOG といった関連する情報については、次の場所にあります。 http://pecl.php.net/package/apc.

この PECL 拡張モジュール用の DLL は、PHP のダウンロード ページあるいは http://pecl4win.php.net/ からダウンロードできます。

注意: Windows 版の APC では、temp パスが存在し、 Web サーバから書き込み可能になっていることが必要です。 APC は環境変数 TMP、TEMP、USERPROFILE の内容をこの順に調べ、 どれも設定されていない場合は WINDOWS ディレクトリを使用します。

注意: さらに深く踏み込んだ、実装についての高度な技術情報は、 developer-supplied TECHNOTES file を参照ください。

実行時設定

php.ini の設定により動作が変化します。

たいていの場合はデフォルトの APC 設定でうまく動作しますが、 きちんとチューニングをしたい場合は以下のパラメータを設定します。

あなたが決めなければいけないことは、以下の 2 つです。 まず APC にどれくらいの共有メモリを設定するかということ、そして、 ファイルの更新チェックをリクエストのたびに APC が行うかどうかということです。 これらに関連する ini ディレクティブが apc.shm_size および apc.stat です。これらのディレクティブについて、 以下の説明を注意深くお読みください。

サーバを起動したら、この拡張モジュールに含まれているスクリプト apc.php をドキュメントルート以下に配置し、 ブラウザでアクセスしてください。 キャッシュの状態についての詳細な情報がここで得られます。 PHP で GD が使用可能になっている場合は、きれいなグラフも表示されます。 まず最初にチェックすべきなのは、当然、 実際にファイルがキャッシュされているかどうかでしょう。 実際に動作していることを確認したら、次は左側にある Cache full count の値に注目しましょう。 これは、キャッシュがいっぱいになったために強制削除が行われた (直近の apc.ttl 秒間にアクセスされなかったエントリが、 キャッシュから削除された) 回数を表します。 この値ができるだけ小さくなるようにキャッシュを設定しなければなりません。 キャッシュが絶えずいっぱいになっているようだと、 パフォーマンスに影響を及ぼします。 この場合は、APC に割り当てるメモリの量を増やすか、 キャッシュするスクリプトを絞り込むために apc.filters を使用します。

表 1. APC の設定オプション

名前デフォルト変更の可否変更履歴
apc.enabled"1"PHP_INI_SYSTEMAPC <= 3.0.12p2 で PHP_INI_ALL。
apc.shm_segments"1"PHP_INI_SYSTEM 
apc.shm_size"30"PHP_INI_SYSTEM 
apc.optimization"0"PHP_INI_ALL 
apc.num_files_hint"1000"PHP_INI_SYSTEM 
apc.user_entries_hint"4096"PHP_INI_SYSTEM 
apc.ttl"0"PHP_INI_SYSTEM 
apc.user_ttl"0"PHP_INI_SYSTEM 
apc.gc_ttl"3600"PHP_INI_SYSTEM 
apc.cache_by_default"1"PHP_INI_ALLAPC <= 3.0.12p2 で PHP_INI_SYSTEM。
apc.filtersNULLPHP_INI_SYSTEM 
apc.mmap_file_maskNULLPHP_INI_SYSTEM 
apc.slam_defense"0"PHP_INI_SYSTEM 
apc.file_update_protection"2"PHP_INI_SYSTEM 
apc.enable_cli"0"PHP_INI_SYSTEM> APC 3.0.6
apc.max_file_size"1M"PHP_INI_SYSTEM> APC 3.0.6
apc.stat"1"PHP_INI_SYSTEM> APC 3.0.9
apc.write_lock"1"PHP_INI_SYSTEM>= APC 3.0.11
apc.report_autofilter"0"PHP_INI_SYSTEM>= APC 3.0.11
apc.include_once_override"0"PHP_INI_SYSTEM>= APC 3.0.12
apc.rfc1867"0"PHP_INI_SYSTEM>= APC 3.0.13
apc.localcache"0"PHP_INI_SYSTEM>= APC 3.0.14
apc.localcache.size"512"PHP_INI_SYSTEM>= APC 3.0.14
PHP_INI_* 定数の詳細および定義については 付録H を参照してください。

以下に設定ディレクティブに関する 簡単な説明を示します。

apc.enabled boolean

apc.enabled を 0 にすることで APC を無効にできます。 APC が静的にコンパイルされて PHP に組み込まれており、 他に無効にする手段がない場合などに有用です (DSO としてコンパイルされている場合は、 単に php.ini の中の extension という行をコメントアウトするだけで無効にできます)。

apc.shm_segments integer

コンパイラキャッシュのために割り当てる共有メモリセグメントの数。 APC が割り当て済みの共有メモリを使い切ってしまっているが、 すでにシステムが許す限り apc.shm_size を拡大しているといった場合に、この値を大きくすることを試みます。

apc.shm_size integer

個々の共有メモリセグメントの大きさを MB 単位で指定します。デフォルトで、 共有メモリセグメントの大きさが非常に小さく設定されているシステムもあります (大半の BSD 系システムがこれに含まれます)。

apc.optimization integer

最適化レベル。ゼロは最適化を無効にし、 値を大きくするほど最適化のレベルが高くなります。 わずかながら速度の向上が期待できます。この項目は実験的なものです。

apc.num_files_hint integer

Web サーバで読み込まれるソースファイルの総数についての 「ヒント」。よくわからない場合はゼロを指定するか、 単に無視してください。 何千ものソースファイルを扱っているようなサイトで有用です。

apc.user_entries_hint integer

apc.num_files_hint と同様に、 保存するユーザキャッシュ変数の数についての「ヒント」。 よくわからない場合は、ゼロを設定するか無視してください。

apc.ttl integer

キャッシュされているエントリが、 他のエントリに割り当てられるまでスロットに残っていることの可能な秒数。 ゼロのままにしておくと、キャッシュの中身が古いエントリでいっぱいになってしまい、 新しいエントリがキャッシュできなくなります。

apc.user_ttl integer

ユーザキャッシュエントリが、 他のエントリに割り当てられるまでスロットに残っていることの可能な秒数。 ゼロのままにしておくと、キャッシュの中身が古いエントリでいっぱいになってしまい、 新しいエントリがキャッシュできなくなります。

apc.gc_ttl integer

キャッシュエントリがガベージコレクションのリストに残り続ける秒数。 ソースファイルのキャッシュ中にサーバプロセスが死んだ場合の安全装置となります。 ソースファイルが変更された場合、メモリに割り当てられている古いバージョンは、 この TTL に達するまで再読み込みされません。 この機能を無効にするにはゼロを設定します。

apc.cache_by_default boolean

デフォルトで On です。しかし、これを Off にして + で始まる apc.filters とともに使用することで、 フィルタに一致したファイルのみをキャッシュすることが可能です。

apc.filters string

カンマで区切られた、POSIX 拡張正規表現のリスト。 ソースファイル名がいずれかのパターンにマッチした場合、そのファイルはキャッシュされません。 マッチングに使用されるファイル名は include/require に渡される名前であり、 絶対パスではないことに注意しましょう。正規表現が + で始まっている場合、その条件にマッチするファイルはキャッシュされます。 また - で始まっている場合は、 条件にマッチするファイルはキャッシュされません。 デフォルトは - なので、これは省略可能です。

apc.mmap_file_mask string

--enable-mmap を用いて MMAP サポートつきでコンパイルされている場合、ここで mktemp 形式のファイルマスクを指定します。mmap モジュールは、 mmap されたメモリ領域をファイルに置くか共有メモリに置くかを、 これによって判断します。 ファイルベースの mmap を使用するには、この値を /tmp/apc.XXXXXX (正確に 6 つの X)のように指定します。 POSIX 形式の shm_open/mmap を使用するには、.shm をマスクのどこかで指定します。例: /apc.shm.XXXXXX 。 また、/dev/zero を指定することで、カーネルの /dev/zero インターフェースを使用した anonymous mmap を使用することもできます。未定義の場合は、この方式が用いられます。

apc.slam_defense integer

非常にアクセスの多いサーバでは、 サーバを起動したりファイルを書き換えたりするたびに 「多くのプロセスが」「同時に」「同じファイルを」 キャッシュしようとすることになります。このオプションを指定すると、 ある一定のパーセンテージでファイルをキャッシュせずに利用するようにします。 あるいは、単一のプロセスがキャッシュ処理をスキップする確率と考えることもできます。 たとえば、apc.slam_defense75 に設定すると、プロセスがキャッシュされていないファイルをキャッシュする処理を 75% の確率で抑えられます。つまり、この値を大きく設定することで、 キャッシュ処理の混雑を防ぐことが可能です。値を 0 に設定すると、この機能が無効になります。

apc.file_update_protection integer

稼動中の Web サーバ上のファイルを書き換える場合、それを原始的(atomic) な手段で行うべきです。つまり、まずいったん一時ファイルに書き込み、 準備ができた時点でそれをリネーム(mv) して正しい位置に移動します。多くのテキストエディタや cp、tar その他のプログラムはこの方式ではありません。 ということは、ファイルの書き込み中にそのファイルがアクセスされる (そしてキャッシュされる)可能性があるわけです。 apc.file_update_protection は、 新しいファイルをキャッシュするまでの遅延を設定します。デフォルトは 2 秒で、ファイルの更新時刻(mtime)がアクセス時刻と 2 秒未満しか違わない場合はファイルをキャッシュしないという意味です。 更新の最中のファイルにアクセスしてしまった不幸な人には 変なデータが見えてしまいますが、 少なくともその変な状態がキャッシュされてしまうことはありません。 rsync などの原始的な更新を保証する方式を利用することがわかっている場合は、 値を 0 に設定することでこの機能を無効にできます。 更新処理に 2 秒以上かかるようなシステムを利用している場合は、 この値をもう少し大きくしたくなるかもしれません。

apc.enable_cli integer

たいていは、テストやデバッグ用に使用します。これを設定すると CLI バージョンの PHP で APC を有効にします。通常は、すべての CLI リクエストに対して APC キャッシュを作成/格納/削除したいとは思わないでしょう。 しかし、CLI バージョンの APC を簡単に作成できるようにしておくことは、 多くのテストシナリオで有用です。

apc.max_file_size integer

この値よも大きなサイズのファイルは、キャッシュされません。 デフォルトは 1M です。

apc.stat integer

この設定を変更する場合は十分注意してください。デフォルト設定は On で、 これは、ファイルが変更されていないかどうかを スクリプトの実行のたびに APC が調べ、 もし変更されていれば、再コンパイルして新しいバージョンをキャッシュします。 この設定を Off にすると、変更されているかどうかがチェックされません。 つまり、変更内容を有効にするには Web サーバを再起動する必要があるということです。 実運用環境ではコードを変更することはめったにないでしょうから、 この設定を Off にしておくことでパフォーマンスを大きく向上させられます。

included/require されたファイルについてもこのオプションは適用されますが、 もし相対パス (Unix の場合は / で始まらないすべてのパス) の include を使用している場合は、ファイルを一意に識別するために APC がチェックする必要があります。 絶対パスの includes を使用している場合、 APC 絶対パスをファイルの識別子として使用し、 チェックを飛ばすことができます。

apc.write_lock boolean

多くの処理が実行されるサーバでは、最初にサーバを立ち上げたときや 多くのファイルを変更した場合などに、 すべてのプロセスが同一のファイルをコンパイルしたりキャッシュしたりしてしまうことがあります。 write_lock を有効にすると、ひとつのプロセスのみが 未キャッシュのスクリプトをコンパイルするようになります。 その間、他のプロセスはロック待ちをするのではなく キャッシュされていない状態で実行します。

apc.report_autofilter boolean

バインド時の問題によりキャッシュから自動的に除外されたスクリプトを記録します。

apc.include_once_override boolean

include_once() および require_once() を最適化し、コストの高いシステムコールの使用を避けるようにします。

apc.rfc1867 boolean

RFC1867 のファイルアップロード進捗ハンドラが有効になるのは、 PHP 5.2.0 以降で APC をコンパイルした場合のみです。 これを有効にすると、ファイルアップロードフォームの file フィールドの前に APC_UPLOAD_PROGRESS というフィールドがある場合に APC が自動的にユーザキャッシュエントリ upload_key を作成します。ここで、key はフォームの APC_UPLOAD_PROGRESS エントリの値となります。

現時点では、ファイルアップロードの追跡はスレッドセーフではないことに注意しましょう。 前のアップロード処理が終わる前に別のアップロードを開始すると、 前のアップロードの追跡が無効になってしまいます。

例 1. apc.rfc1867 の例

<?php
print_r
(apc_fetch("upload_$_POST[APC_UPLOAD_PROGRESS]"));
?>

上の例の出力は、たとえば 以下のようになります。

Array
(
    [total] => 1142543
    [current] => 1142543
    [rate] => 1828068.8
    [filename] => test
    [name] => file
    [temp_filename] => /tmp/php8F
    [cancel_upload] => 0
    [done] => 1
)

apc.localcache boolean

これは、ロックが不要なローカルプロセスのシャドウキャッシュを有効にします。 これにより、キャッシュが書き込まれる際のロックの競合を軽減します。

apc.localcache.size integer

ローカルプロセスのシャドウキャッシュの大きさ。 ある程度大きなな値を設定しておく必要があります。目安としては apc.num_files_hint の半分程度となります。

リソース型

リソース型は定義されていません。

定義済み定数

定数は定義されていません。

目次
apc_add --  変数をデータ領域にキャッシュする (保存されていない場合のみ)
apc_cache_info --  APC のデータから、キャッシュされた情報(およびメタデータ)を取得する
apc_clear_cache --  APC キャッシュをクリアする
apc_define_constants --  定数の組を定義し、それを取得あるいは一括定義する
apc_delete --  格納されている変数をキャッシュから取り除く
apc_fetch --  格納されている変数をキャッシュから取得する
apc_load_constants --  定数群をキャッシュから読み込む
apc_sma_info --  APC の共有メモリ割り当てに関する情報を取得する
apc_store --  変数をデータ領域にキャッシュする