It seems there are issues when using APC to cache database result sets as PDOStatements. Any attempts I have made always result in an exception being thrown with the message: 'You cannot serialize or unserialize PDOStatement instances'
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 を使用します。
| 名前 | デフォルト | 変更の可否 | 変更履歴 |
|---|---|---|---|
| apc.enabled | "1" | PHP_INI_SYSTEM | APC 2 で PHP_INI_SYSTEM。APC <= 3.0.12 で 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 3.0.0 以降で利用可能。 |
| apc.ttl | "0" | PHP_INI_SYSTEM | APC 3.0.0 以降で利用可能。 |
| apc.user_ttl | "0" | PHP_INI_SYSTEM | APC 3.0.0 以降で利用可能。 |
| apc.gc_ttl | "3600" | PHP_INI_SYSTEM | |
| apc.cache_by_default | "1" | PHP_INI_ALL | APC <= 3.0.12 で PHP_INI_SYSTEM。APC 3.0.0 以降で利用可能。 |
| apc.filters | NULL | PHP_INI_SYSTEM | |
| apc.mmap_file_mask | NULL | PHP_INI_SYSTEM | |
| apc.slam_defense | "0" | PHP_INI_SYSTEM | APC 3.0.0 以降で利用可能。 |
| apc.file_update_protection | "2" | PHP_INI_SYSTEM | APC 3.0.6 以降で利用可能。 |
| apc.enable_cli | "0" | PHP_INI_SYSTEM | APC 3.0.7 以降で利用可能。 |
| apc.max_file_size | "1M" | PHP_INI_SYSTEM | APC 3.0.7 以降で利用可能。 |
| apc.stat | "1" | PHP_INI_SYSTEM | APC 3.0.10 以降で利用可能。 |
| 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.rfc1867_prefix | "upload_" | PHP_INI_SYSTEM | |
| apc.rfc1867_name | "APC_UPLOAD_PROGRESS" | PHP_INI_SYSTEM | |
| apc.rfc1867_freq | "0" | PHP_INI_SYSTEM | |
| apc.localcache | "0" | PHP_INI_SYSTEM | APC 3.0.14 以降で利用可能。 |
| apc.localcache.size | "512" | PHP_INI_SYSTEM | APC 3.0.14 以降で利用可能。 |
以下に設定ディレクティブに関する 簡単な説明を示します。
- 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_defense を 75 に設定すると、プロセスがキャッシュされていないファイルをキャッシュする処理を 75% の確率で抑えられます。つまり、この値を大きく設定することで、 キャッシュ処理の混雑を防ぐことが可能です。値を 0 に設定すると、この機能が無効になります。
非推奨です。かわりに apc.write_lock を使用しましょう。
- 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 エントリの値となります。
現時点では、ファイルアップロードの追跡はスレッドセーフではないことに注意しましょう。 前のアップロード処理が終わる前に別のアップロードを開始すると、 前のアップロードの追跡が無効になってしまいます。
Example#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.rfc1867_prefix string
-
rfc1867 のアップロード進捗処理機能で作成するユーザキャッシュエントリの キーにつけるプレフィックスを指定します。
- apc.rfc1867_name string
-
APC のアップロード進捗処理機能を有効にするフォームの hidden 項目名、そしてユーザキャッシュエントリのキーのサフィックスを指定します。
- apc.rfc1867_freq string
-
アップロードの進捗を記録するユーザキャッシュエントリの更新頻度を指定します。 ファイルサイズに対するパーセンテージ、あるいはファイルサイズで指定します。 サイズを指定する場合は、最後に 'k'、'm' あるいは 'g' を指定することでそれぞれキロバイト、メガバイト、ギガバイトを指定できます (大文字小文字は区別しません)。 0 を指定すると、可能な限り進捗を更新するようにします。 これは、アップロードの速度を低下させてしまいます。
- apc.localcache boolean
-
これは、ロックが不要なローカルプロセスのシャドウキャッシュを有効にします。 これにより、キャッシュが書き込まれる際のロックの競合を軽減します。
- apc.localcache.size integer
-
ローカルプロセスのシャドウキャッシュの大きさ。 ある程度大きなな値を設定しておく必要があります。目安としては apc.num_files_hint の半分程度となります。
リソース型
リソース型は定義されていません。
定義済み定数
定数は定義されていません。
目次
- apc_add — 変数をデータ領域にキャッシュする (保存されていない場合のみ)
- apc_cache_info — APC のデータから、キャッシュされた情報(およびメタデータ)を取得する
- apc_clear_cache — APC キャッシュをクリアする
- apc_compile_file — ファイルをバイトコードキャッシュに保存し、すべてのフィルタをバイパスする
- apc_define_constants — 定数の組を定義し、それを取得あるいは一括定義する
- apc_delete — 格納されている変数をキャッシュから取り除く
- apc_fetch — 格納されている変数をキャッシュから取得する
- apc_load_constants — 定数群をキャッシュから読み込む
- apc_sma_info — APC の共有メモリ割り当てに関する情報を取得する
- apc_store — 変数をデータ領域にキャッシュする
APC
20-Sep-2007 08:53
30-Jul-2007 10:21
Keep in mind to always prefix or suffix your cache key names with something specific to your site/app/setup, to avoid the risk of your apc cache entries being overwritten/deleted/modified by someone else on the same server.
Assume we have some code like this:
apc_store('config', $cfg);
Now assume someone else on the same server is also using 'config' as the key passed to an apc_store(), apc_delete() (etc.) call in some other piece of code on the whole server.
Since you're both working on the exact same cache entry, all sorts of wierd things can happen, but the problem is not in your code at all.
03-Jul-2007 04:28
If you don't want any APC info visible without logging in, insert this code at line 173 of apc.php:
<?
if (!$AUTHENTICATED) {
echo '<div class="authneeded">You need to login to see the user values here!<br/> <br/>';
put_login_link("Login now!");
echo '</div>';
die();
}
?>
24-May-2007 12:14
In IIS6 you can't use php_apc.dll with application pools or webgardens (Multi-Instance/Multi-Threading). Maybe this applies even to all Multithreading environments - i don't know.
When you try it, the Application pools terminate when requests run simultaneously.
04-Apr-2007 11:37
An improvement on ashus at atlas dot cz's script below would be to add around the script that generates the output:
<?php
//...
ob_start ();
// script goes here
$out = ob_get_content();
ob_end_clean ();
//...
?>
That way you can continue to use echo rather than string concatenation, and it should be a little faster.
21-Mar-2007 11:56
If you don't really need caching and plan to use it for one page only, you could try an alternative; writing a file and then flushing it back if specified time hasn't passed. I use it to read and parse third party websites, to check for new subtitles and output a RSS xml file.
<?php
if ((is_file($_SERVER['SCRIPT_FILENAME'].'.cached'))
&& (time()-filemtime($_SERVER['SCRIPT_FILENAME'].'.cached') < 3600))
{
readfile($_SERVER['SCRIPT_FILENAME'].'.cached');
exit;
}
// (the php script itself goes here)
echo $out;
$fp = fopen($_SERVER['SCRIPT_FILENAME'].'.cached', 'w');
fwrite($fp, $out);
fclose($fp);
?>
Note, that this only works for pages, which are without GET or POST variables, sessions, etc. You can change the number of seconds the cache works for (3600 = an hour). Also, use "$out.=" instead of "echo" command. Just store all output to that variable (if you need to use it inside a function, use "global $out" instead).
This workaround was written in about 5 minutes and may contain bugs.
31-Jan-2007 11:14
In windows, if you load php_apc.dll but do not enable it, apache may crash when attempting to restart or stop.
So, if you've not enabled APC but are loading it, comment out the loading.