nginxでリバースプロキシかましてキャッシュさせることでパフォーマンスを稼ぐっていうのは、わりとよくあるシチュエーションなんですが、キャッシュ自体のコントロールっていうのが、案外忘れがちというか、置いてけぼりになることが多いので、キャッシュを削除できる環境を作るメモです。
nginxのリバースプロキシ設定
まず、nginxはデフォルトでキャッシュする機能があるので設定するだけでいけます。下記の設定は、単なるWebサーバ https://example.com をバックエンドとして、全URLをキャッシュする設定です。
http {
proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=zone1:4m inactive=7d max_size=50m;
proxy_temp_path /var/cache/nginx/tmp;
}
server {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_ignore_headers Cache-Control;
proxy_cache zone1;
proxy_cache_key $uri;
proxy_cache_valid 200 302 1m;
proxy_cache_valid 404 10m;
location / {
proxy_pass https://example.com;
}
}
proxy_cache_path
ここのパラメータが毎回分からなくなるのでメモ。第1パラメータはキャッシュファイルを保存する場所です。
キー | 値 |
---|---|
levels | キャッシュを保存するディレクトリ階層とディレクトリ名に使用される文字数になります。1:2 だと/1/01 に、2:2:2 だと/01/01/01 になります。ただし階層を増やしたり、文字数を増やすとその分ディレクトリが作成されることになるので、inode枯渇で死ぬケースもあるようです。参考 nginxのキャッシュ階層を深くしすぎてinodeが枯渇した
|
keys_zone | proxy_cacheディレクティブで指定するキーです。コロン区切りで、共有メモリの容量指定ができます。1MBにつき約8000個のキャッシュメタデータを保存できるようです |
inactive | 指定した期間後、自動的にキャッシュが削除されます。デフォルトだと10分に設定されています |
max_size | キャッシュのファイルサイズ上限です。keyz_zoneのメモリと、max_sizeどちらかが枯渇した時点でキャッシュが停止します |
キャッシュを削除する
キャッシュを消したい場合は、proxy_cache_path
の中にある該当ファイルを消せばOKなのだけど、いちいちそんな手動で消すの面倒くさいし、ログインしなきゃいけないのでありえんとなるわけです。下記コマンドの様にURLからキャッシュファイルを特定するコマンドもありますけど…。
find /var/cache/nginx/example.com -type f -exec grep -l "KEY: http://example.com/$" {} \; | xargs rm -f
キャッシュ可能なURLを作成する
本題です。nginxデフォルトだとキャッシュを削除する機能はありません。そこでnginxモジュールngx_cache_purge
を使用します。
ngx_cache_purgeをnginxに組み込むには、nginxをソースからビルドして上げる必要があります。はい、面倒くさいですね。nginx自体パッケージからインストールしているし…という人には、nginxのビルドを自動化できるツールnginx-build
を利用しましょう。モジュールも超簡単に導入できます。
もしくは、Itamaeであれば僕が以前作ったItamaePluginがあるので、それを使っても良いと思います。
ngx_cache_purge
を導入したら、設定ファイルにキャッシュを削除する用のURLディレクティブを指定します。この例だと/hoge/piyo
のURLをキャッシュしていたとしたら/purge/hoge/piyo
にアクセスするとキャッシュが削除できます。
server {
location ~ ^/purge(/.*) {
allow 127.0.0.1;
deny all;
proxy_cache_purge zone1 $1;
}
}
アプリケーション側からは、データソースの変更があったタイミングで削除用のURLを叩くとキャッシュがクリアされるように出来ると思います。簡単ですね。