APCの動作 3 設計と設定

前回前々回からの続き。

APCの設定というと、FacebookでのAPC使用方法を紹介したapc@facebookがとっても有用。
内容については、id:i_ogiさんがまとめられているfacebookでのAPCの設定というエントリーを読むのがおすすめ。


といっても、APCを使うサイト全てがFacebook並みの規模があるわけでもないので、apc@facebookを横目で見ながら目の前のサイトに合った設定を探すのだ。(Userキャッシュは使ってないので無視だ)

apc.shm_size

使用するメモリのサイズ。キャッシュ対象の全ファイルがキャッシュされた状態でも余りが出るように設定する。
ただし、1KBのファイルが1KBのメモリを消費するわけではないので注意。
目安としては

 クラス > 関数 > ベタ書き処理 > テキスト

の順で元よりサイズが大きくなる。元のファイルサイズの大体5〜6倍程度で計算すれば良いと思う。
実際のサイズはapc.phpapc_cache_info()で確認できる。


割り当てられるメモリが少ないとか、PHPの量がとんでもないという場合にはapc.filtersを使って除外してみる。呼び出しが多い共通のクラスはキャッシュして、場末のSmartyコンパイルキャッシュは外すなど。
そのためには正規表現が書きやすいようなディレクトリ構成やファイル命名規則にしておく必要がある。


メモリの割り当てが少ないとexpunge(Cache full)が発生してしまう。
expungeはパフォーマンスに悪影響を与えるので可能な限り避ける。

apc.num_files_hint

ちゃんと数えて設定する。この手の数字は素数だとハッシュの衝突が少ないらしいけど、2倍されてしまうならどうやっても素数にはならない気がする。

apc.stat

これが一番悩ましい。
offにした方が通常時のパフォーマンスは良いのだろうけど、管理上の問題がある。


offの場合はファイルの更新をした後にサーバの再起動かapc_cache_clear()を実行する必要があるけど、そうすると全てのキャッシュが消えてしまう。
キャッシュが消えた後で一気にアクセスが来ると、各プロセスがキャッシュを作ろうとしてあんまり良くない*1
それに、滅多に呼ばれないファイルを更新しただけの場合でも、必ず呼ばれるファイルのキャッシュを消さなきゃならないのも嬉しくない。


サーバを切り離してapc_compile_file()する(Facebook方式)というのも手だけど、そこまでしたくないし、ファイル数が多いと現実的じゃないし*2、更新が頻繁にあるサイトだと苦しいし。


だったらonにしておけば良いかというとそうでもない。
ファイルの更新にrsync,svn upなどを使っている場合、キャッシュを消さないとどんどんメモリの使用量が増えてしまい、いつかexpungeが発生してしまう。
また、Smartyを使用していてコンパイルキャッシュをAPCでキャッシュしている場合も、テンプレートファイルを更新する度に*3メモリ使用量が増えてしまう。


折衷案としては、statはonにし、アクセスが少ない時間にapc_chache_clear()をGC代わりに実行するなど。
ちなみに、logrotateでApacheにHUPを送るとキャッシュがクリアされるよやったね!


onにする場合はshm_sizeに更なる余裕を。

apc.ttl

stat=offの場合は0でOK。
stat=onの場合は、expnugeが発生した場合に備えて大き過ぎず小さ過ぎずの値にしておくのが良いと思う。具体的には1〜3時間くらい。



APCについてはこれでおしまい。

*1:apc.slam_defense

*2:apc@facebookによるとFacebookのnum_files_hintは100

*3:更新されているか確認する設定の場合