nginx でリバースプロキシのキャッシュを削除する方法は、一応、色々な方法があります。
以前に上記の記事の中でも一部に削除方法について書いています。
今回は、散在している内容をまとめて、ちょっと、掘り下げて簡単に解説してみます。
- 目次
- 履歴
2014年2月3日 FastCGIキャッシュの削除方法も追記
2013年3月1日 初版
nginx でキャッシュを削除する方法(まとめ)
先のとおりキャッシュを削除する方法は、いろいろあります。それぞれについて簡単に解説してみます。
時間経過による自動削除を待つ
これは、削除するというより、何もしないだけです。例えば、nginxのプロキシ設定(nginx.conf)が以下のような設定となっていた場合、
リバースプロキシ キャッシュ の場合
|
上記のproxy_cache_pathディレクティブのinactiveパラメータは、指定された時間の間要求がない場合は、キャッシュから削除されます。
そのため、ここでは、1h(1時間)間、だれからもアクセスされなかったら、そのページはキャッシュから削除されます。
また、proxy_cache_validディレクティブは、HTTPステータスコード毎にキャッシュ時間を設定します。
ここでの設定では、HTTPステータスコードが200(正常)の場合は、最大2h(2時間)でキャッシュを解放(削除)します。
上記の設定では、早くて1時間、長くて2時間後には、キャッシュから削除されます。
FastCGI キャッシュ の場合
|
基本ディレクティブ名が proxy_cache_path → fastcgi_cache_path のように変化するだけです。
設定するパラメータも同じのため、上記のリバースプロキシ キャッシュ の場合 を参照してください。
キャッシュディレクトリの配下の全ファイルを丸ごと削除する
これは、非常に簡単なやり方で、例えば、nginxのプロキシ設定(nginx.conf)が以下のような設定となっていた場合、
リバースプロキシ キャッシュ の場合
|
キャッシュゾーン名: cache_example.com は、キャッシュディレクトリとして、/var/cache/nginx/example.com を使用します。
このディレクトリを削除してしまえばよいわけです。
|
これで一発で削除できるというわけです。
ただ、これは、サイト全体のキャッシュを削除してしまうのには、非常に便利ですが、例えば、1つのページのみが更新された場合などは、
サイト全体のキャッシュを削除する必要はないわけで、毎回、1つ、2つのページの更新のためにサイト全体のキャッシュを削除していては
無駄も多いですし、負荷もかかりやすくなってしまうというデメリットもあります。
FastCGI キャッシュ の場合
|
基本ディレクティブ名が proxy_cache_path → fastcgi_cache_path のように変化するだけです。
設定するパラメータも同じのため、上記のリバースプロキシ キャッシュ の場合 を参照してください。
nginx cache purge モジュールを組み込んでウェブからキャッシュファイルを削除する
→ Nginxのproxyでキャッシュを削除する方法 にて詳しく解説していますので、そちらを参照してください。
このやり方は、確かにページ毎のキャッシュを削除してくれるという点では、非常にありがたいのですが、nginxも結構頻繁に更新がかかりますから、
その都度、nginx cache purge モジュールを組み込むために自前でビルド(make)作業が必要なのがデメリットです。
キャッシュファイルを検索して、該当するキャッシュファイルを削除する
これは、Unix系(Linuxも含む)OSでは、非常に便利、簡単なやり方です。
先のキャッシュディレクトリの一括削除と同じ以下の例で解説しています。
例えば、nginxのプロキシ設定(nginx.conf)が以下のような設定となっていた場合、
リバースプロキシ キャッシュ の場合
|
キャッシュゾーン名: cache_example.com は、キャッシュディレクトリとして、/var/cache/nginx/example.com を使用します。
このディレクトリからキャッシュを削除したいURL情報をもとにキャッシュファイルを検索し、削除してしまいます。
|
これは、キャッシュファイルの中にKEY情報が埋め込まれていることを利用して該当するキャッシュファイルをディレクトリから検索をかけて、
キャッシュファイルがあれば削除するということを1行で行っています。
FastCGI キャッシュ の場合
|
基本ディレクティブ名が proxy_cache_path → fastcgi_cache_path のように変化するだけです。
設定するパラメータも同じのため、上記のリバースプロキシ キャッシュ の場合 を参照してください。
キャッシュファイル名を求めて、該当するキャッシュファイルを削除する
上記と異なり、キャッシュファイルを検索せずにキャッシュファイルをURLから求めることもできます。
以下は、その例です。
|
このやり方は、nginxのキャッシュファイルの命名方法を利用したものです。
nginxは、キャッシュファイルの命名方法、格納ディレクトリの指定を以下の手順で行っています。
- キャッシュ対象のURLをMD5でハッシュ変換し、ファイル名とする
シェルであれば、以下のようなイメージです。
$ echo -n "http://example.com/" | md5sum a6bf1757fff057f266b697df9cf176fd -
ここで有効な情報は、 – の手前までです。
- nginx.confのproxy_cache_path (or fastcgi_cache_path) で設定しているlevelsパラメータからディレクトリを決定する
上記のnginx.confの設定例では、levels=1:2 となっています。
- リバースプロキシ キャッシュ の場合
... proxy_cache_path /var/cache/nginx/example.com levels=1:2 keys_zone=cache_example.com:15m inactive=1h max_size=1000m; ...
- FastCGI キャッシュ の場合
... fastcgi_cache_path /var/cache/nginx/example.com levels=1:2 keys_zone=cache_example.com:15m inactive=1h max_size=1000m; ...
この意味は、
ディレクトリの1階層目は、先のURLをハッシュ値へ変換した末尾から1文字を使用します。
ディレクトリの2階層目は、先のURLをハッシュ値へ変換した末尾+1から2文字を使用します。
つまり、上記の http://example.com/ のハッシュ値を例に解説すると、6f , d がそれぞれのディレクトリ階層になります。
a6bf1757fff057f266b697df9cf176fd
シェルであれば、以下のようなイメージです。
$ echo -n "http://example.com/" | md5sum | awk '{print "level1:"substr($1,length($1),1)" level2:"substr($1,length($1)-2,2)}' level1:d level2:6f
- リバースプロキシ キャッシュ の場合
- nginx.confのproxy_cache_path (or fastcgi_cache_path) で設定しているキャッシュディレクトリと上記のキャッシュディレクトリ、キャッシュファイル名を結合する
最後は、上記で求めたディレクトリ名、ファイル名とnginx.confのproxy_cache_path (or fastcgi_cache_path) で設定しているキャッシュディレクトリとを結合してキャッシュファイルのフルパスとします。
これは、シェルでは以下のようにできます。$ echo -n "http://example.com/" | md5sum | awk '{print "/var/cache/nginx/example.com/"substr($1,length($1),1)"/"substr($1,length($1)-2,2)"/"$1}' /var/cache/nginx/example.com/d/6f/a6bf1757fff057f266b697df9cf176fd
最初に紹介したコマンドイメージの 最後の | xargs rm -f を除いたイメージです。
ついでに削除する phpスクリプトを作ってみた(おまけ)
個々のページ毎のキャッシュファイルを削除する方法をphpコードで書くと、以下のようになります。
|
|
ちょっと長くなりましたが、これってコマンドラインで、キャッシュディレクトリ、URL、LEVELSを指定すると自動的に削除してくれるというもので、
パラメータのチェックや使い方、デバッグ情報の出力のために長くなっていますが、やっていることは、上記のMD5でファイルパスを作って、
一応、念のためにキャッシュファイルの中のKEY情報 と比較して一致したら削除しています。
上記の exmaple.com の例をこのphpスクリプトで実行すると以下のようになります。
ここでは、このphpスクリプトのファイル名を rm_cache.php としています。
|
最後のキャッシュファイルを検索して、該当するキャッシュファイルを削除する方法では、2つのやり方を簡単に解説してみました。
いずれでも良いとは思いますが、やっぱり、後者が理に適っていると思います。
これをうまく利用すれば、nginx cache purge モジュールを組み込む必要もなくなりますから、CentOS,Scientific Linux,Debian,Ubuntuでは、 nginxから最新版のバイナリで常に更新できるようになります。 もし、nginx cache purge モジュールを組み込んでおられる方には、おすすめな方法だと思います。
このサイトでは、コンテンツの一部が非表示、あるいは、コメント、お問い合わせの投稿ができない、検索ができないことがあります。
2014年1月22日, 5:15 PM
キャッシュディレクトリの中を削除してもメモリに残ったキャッシュは消えないので、期待通りの効果は得られませんよ。
2014年1月22日, 11:17 PM
nginx愛好家 さん
コメントありがとうございます、管理人です。
おっしゃってるのは、HttpMemcachedModuleを使っている場合の話?それとも??
ちょっと正確なところがよく理解できていません、すみません。
どういう時にメモリに残る?のか、理解できていない情けない私に、もう少し具体的にご教示いただけませんでしょうか?
よろしくお願い申し上げます。
単純にディスクキャッシュだけを使っている場合、キャッシュファイルを削除すれば、概ね動く?というより、現状、このサイトは、(FCGICacheですが)期待どおりの動作をしています。メモリが厳しい1GBのさくらなので、メモリキャッシュが使える状態でないことも確か?なのですが、 キャッシュされている時は、それなりの動作なので、それなりに満足しています。一応、ご参考までに。