リアルタイムに状態が変わるようなサイトでは、部分的にデータをキャッシュすることはあってもページ全体をキャッシュすることはないと思います。
しかし、ページ全体が数日に 1 回や、数時間に 1 回程度の更新頻度の場合、ページ全体を Web サーバ側でキャッシュしておくことで、裏側で動的な処理を行うプログラムを実行しなくても済みます。
これにより、裏側で動作するプログラムや、データベースへのアクセスが軽減され、Web サーバ以外のリソースはそれほど使わなくても済みます。
この Web サーバのキャッシュですが、nginx の場合は FastCGI キャッシュと proxy キャッシュなどがありますが、今回は FastCGI キャッシュを取り扱います。
キャッシュの個別クリア
キャッシュする時間や、一定時間アクセスがなかった場合のクリア時間、キャッシュに使う容量などは nginx の設定ファイルでしますが、このキャッシュの自体はファイルで作成されます。
よって、キャッシュを強制的にクリアしたい場合は、このキャッシュファイルを削除することになります。
キャッシュファイルには、キー(KEY)として URL のパスを持っているので、これを特定することで個別にキャッシュクリアすることも可能です。
KEY: /hoge/fuga
個別ページの削除は以下の通りです。キャッシュファイルは /var/run 以下にあるものとし、サイト毎にさらにディレクトリが分かれています。
キャッシュのゾーン名が hoge の場合は、/var/run/hoge-cache 以下にキャッシュが生成されます。/hoge/fuga のキャッシュをクリアする場合は以下のようにします。
1 | $ grep -R 'KEY: /hoge/fuga$' /var/run/hoge-cache | awk '{print $3}' | xargs rm -f |
awk を使っているのは grep の結果でバイナリファイルとみなされ以下のように出力されるので、ファイルパス部分を抜き出しています。
grep の -a オプションでバイナリを無視しても、キー名も結果に付いてきて、結局コロンでセパレートしないといけないので、現状はこのようにしています。
また、KEY に指定しているキー名は nginx の設定の fastcgi_cache_key で指定したものになります。
設定によってはドメイン部分からキーが生成されている場合もあると思いますので、キャッシュファイルの中身を見て確認してみてください。
1 2 3 4 | [grep -R] Binary file /var/run/hoge-cache/0/6f/cd1c58e3ebd935ea04f4cefba048f6f0 matches [grep -aR] /var/run/hoge-cache/0/6f/cd1c58e3ebd935ea04f4cefba048f6f0:KEY: /hoge/fuga |
キャッシュの全体クリア
同じゾーン名のキャッシュをすべてクリアするには、キー名をスラッシュだけにすることで全部が該当するので、それをまとめて削除してあげます。
1 | $ grep -R 'KEY: /' /var/run/hoge-cache | awk '{print $3}' | xargs rm -f |
URLのパス毎にキャッシュ時間を設定
残念なのは FastCGI キャッシュの場合、URL のパス毎にキャッシュ時間が設定できないところです。
キャッシュするかしないかは nginx の設定で「fastcgi_no_cache」や「fastcgi_cache_bypass」の値を動的にすることで可能なのですが、時間はゾーン全体に掛かってしまうようです。
別途、「fastcgi_cache_valid」で HTTP のステータスコードごとにキャッシュ時間は設定できるようですので、もしかすると方法があるのでしょうか。