レンタルサーバー・自宅サーバー設定・構築のヒント
レンタルサーバー・自宅サーバー設定・構築のヒント - レンタルサーバー・自宅サーバーの設定・構築情報を公開しています。

Apache でディスクキャッシュを削除する方法をまとめて解説してみた

2013年4月16日 2014年1月10日
apache cache remove

Apache でキャッシュを削除する方法は、一応、公式なものは、htcachecleanを使っての削除のみです。

ただ、nginxと異なり、有効期限を過ぎてもキャッシュファイルは削除されません。
これについては、上記の記事の中でも書きました。

また、上記の方法以外にも、シェルからrm コマンドで キャッシュファイル、あるいはキャッシュディレクトリを直接削除することはできます。

そこで、今回は、Apacheのmod_disk_cacheで作成されたキャッシュファイルの削除方法にについてまとめてみます。

Apache でキャッシュを削除する方法(まとめ)

先のとおりキャッシュを削除する方法は、いろいろあります。それぞれについて簡単に解説してみます。

時間経過による無効を待つ

これは、削除ではなく、時間の経過によってキャッシュが無効になるだけで、使われないだけです。例えば、Apacheのキャッシュ設定(httpd.conf)が以下のような設定となっていた場合、

<VirtualHost *:80>
	...
	ServerName www.example.com
	...
	DocumentRoot /var/www/html
	...
	<IfModule mod_disk_cache.c>
		...
		CacheDirLevels 2
		CacheDirLength 1
		...
		CacheDefaultExpire 3600
		CacheMaxExpire 7200
		...
	</IfModule>
 
</VirtualHost>

上記のCacheMaxExpireディレクティブに キャッシュの最大有効時間(秒)を設定することで、そのキャッシュの有効期限が設定されます。
ただ、有効期限が設定されるだけで、実際にキャッシュが削除されるわけではありません。 次に有効期限が切れたURLへアクセスした際にキャッシュが更新されるだけです。
上記の設定では、早くて1時間、長くて2時間後には、キャッシュが無効、あるいは更新されます。


キャッシュディレクトリの配下の全ファイルを丸ごと削除する

これは、非常に簡単なやり方で、例えば、Apacheのキャッシュ設定(httpd.conf)が以下のような設定となっていた場合、

<VirtualHost *:80>
	...
	ServerName www.example.com
	...
	DocumentRoot /var/www/html
	...
	<IfModule mod_disk_cache.c>
		...
		CacheDirLevels 2
		CacheDirLength 1
		...
		CacheRoot /tmp/cache
		...
	</IfModule>
 
</VirtualHost>

キャッシュディレクトリとして、/tmp/cache を使用します。
このディレクトリを削除してしまえばよいわけです。

$ rm -fR /tmp/cache/*

これで一発で削除できるというわけです。
ただ、これは、サイト全体のキャッシュを削除してしまうのには、非常に便利ですが、例えば、1つのページのみが更新された場合などは、 サイト全体のキャッシュを削除する必要はないわけで、毎回、1つ、2つのページの更新のためにサイト全体のキャッシュを削除していては 無駄も多いですし、負荷もかかりやすくなってしまうというデメリットもあります。


htcacheclean で削除する

Apacheのキャッシュを削除するhtcachecleanを使ってみる にて詳しく解説していますので、そちらを参照してください。

htcacheclean は、Apacheで公式に提供している mod_disk_cache でキャッシュされたファイルを削除するためのツールです。 ただ、これでも、URL指定で個別のキャッシュファイルを削除することはできません。 このツールは、あくまでキャッシュの総量をキープするために古いキャッシュから削除していくようになっているだけで、 無効(有効期限を過ぎた)となったキャッシュをリアルタイムで削除してくれません。先にも書いたように、あくまで、キャッシュの総量をトリガーに古いものから削除するだけです。


キャッシュファイルを検索して、該当するキャッシュファイルを削除する

これは、Unix系(Linuxも含む)OSでは、非常に便利、簡単なやり方です。
先のキャッシュディレクトリの一括削除と同じ以下の例で解説しています。

例えば、Apacheのキャッシュ設定(httpd.conf)が以下のような設定となっていた場合、

<VirtualHost *:80>
	...
	ServerName www.example.com
	...
	DocumentRoot /var/www/html
	...
	<IfModule mod_disk_cache.c>
		...
		CacheDirLevels 2
		CacheDirLength 1
		...
		CacheRoot /tmp/cache
		...
	</IfModule>
 
</VirtualHost>

上記では、キャッシュディレクトリとして、/tmp/cache を使用しています。
このディレクトリからキャッシュを削除したいURL情報をもとにキャッシュファイルを検索し、削除してしまいます。

$ find /tmp/cache -type f -name "*.header"  -exec grep -l "http://example.com:80/?Expires:" {} \; | sed -e s/\.header/\.\*/g | xargs rm -f

これは、キャッシュファイルの中に、以下の形式で有効期限情報が埋め込まれていることを利用して該当するキャッシュファイルをディレクトリから検索をかけています。

$scheme://$host:$port$request_uri[?]Expires:

キャッシュファイルが存在すれば まとめて削除する(キャッシュファイルは、.header ファイルと .data ファイルの2つが存在します) ということを1行で行っています。

  • $scheme : http or https などのスキーマ定義になります。
  • $host : ホスト名になります。
  • $port : ポート番号になります。デフォルトのHTTPであれば、80のはずです。
  • $request_uri : 要求URLになります。ここで ? が使用されない場合は、最後に ? を付けるようです。
    例えば、
    htp://www.exmaple.com/redme.html の場合、htp://www.exmaple.com:80/redme.html? となります。
    また、
    htp://www.exmaple.com/index.php?p=10 の場合、htp://www.exmaple.com:80/index.php?p=10 となります。

キャッシュファイル名を求めて、該当するキャッシュファイルを削除する(おまけ)

キャッシュファイルを検索せずにキャッシュファイル名をURLから変換して求めることもできます。
URLからキャッシュファイル名の変換方法は、nginxのやり方 に近いですが、URLの文字列 から md5sumへ変換した後、20文字列へ変換するところがひと手間あります。
このやり方は、シェル1行で変換できそうもないので、phpで記述したスクリプトを以下に載せておきます。参考までに。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?php

if($argc>=4){
	//	chek of parameters
	$params = array(
		'-c' => array( 'pattern' => '/-c=([^\s]*)/i', 'required' => true ,'valindex' => 1 ),
		'-l' => array( 'pattern' => '/-l=([^\s]*)/i', 'required' => true ,'valindex' => 1),
		'-u' => array( 'pattern' => '/-u=([^\s]*)/i', 'required' => true ,'valindex' => 1),
		'-d' => array( 'pattern' => '/-d/i' , 'required' => false ,'valindex' => 0),
	);
	for($ni=1;$ni<$argc;$ni++){
		foreach($params as $pkey => $param){
			$output = array();
			if(preg_match ( $param['pattern'], $argv[$ni],$output)){
				$params[$pkey]['val'] = $output[$param['valindex']];
				break;
			}
		}
	}
	foreach($params as $pkey => $param){
		if($param['required'] && empty($param['val'])){
			echo 'error : do not input "'.$pkey.'" paramater.'."\n";
			return;
		}
	}
 
	//	set of parameters
	$cach_path = $params['-c']['val'];
	$file_key_org  = $params['-u']['val'];
	$file_key  = md5($params['-u']['val']);
	$level_keys= preg_split("/:/", $params['-l']['val']);
	$debug = !empty($params['-d']['val']);

	//	convert apache
	$digest = array();
	$enc_table =	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_@";

	$hex_v = '';
	for($n=0,$k=0;$n<16;$n++,$k+=2){
		$hex_v = substr($file_key,$k,2);
		sscanf($hex_v, "%x", $digest[$n]);
	}

	$tmp = array();
	for ($i = 0, $k = 0; $i < 15; $i += 3) {
		$x = ($digest[$i] << 16) | ($digest[$i + 1] <<| $digest[$i + 2];
		$tmp[$k++] = $enc_table[$x >> 18];
		$tmp[$k++] = $enc_table[($x >> 12) & 0x3f];
		$tmp[$k++] = $enc_table[($x >> 6) & 0x3f];
		$tmp[$k++] = $enc_table[$x & 0x3f];
	}
	
	$x = $digest[15];
	$tmp[$k++] = $enc_table[$x >> 2];
	$tmp[$k++] = $enc_table[($x << 4) & 0x3f];
	
	$file_key_c = implode("",$tmp);

	if(substr($cach_path,-1,1)==DIRECTORY_SEPARATOR){
		$cach_file = substr($cach_path,0,-1);
	} else {
		$cach_file = $cach_path;
	}
	$offset = 0;
	foreach($level_keys as $level){
		$ilevel = intval($level);
		$cach_file .=  DIRECTORY_SEPARATOR.substr($file_key_c,$offset,$ilevel);
		$offset += $ilevel;
	}
	if($offset>0){
		$file_key_c = substr($file_key_c,$offset);
	}
 
	//	create cache file name.
	$success = false;
	$cach_file_d  =  $cach_file;
	$cach_file   .=  DIRECTORY_SEPARATOR.$file_key_c.'.header';
	$cach_file_d .=  DIRECTORY_SEPARATOR.$file_key_c.'.data';
	$cach_file_exist =  file_exists($cach_file);
	if($cach_file_exist){
		$file_content = file_get_contents($cach_file);
		if(strpos($file_content,$file_key_org )!==false){
			//	sure file, remove the cache
			if(!$debug) {
				@unlink($cach_file_d);
				$success = unlink($cach_file);
			} else {
				$success = true;

			}
		}
	}
	if($success) {
		echo 'Removed:'.$cach_file."\n";
		echo 'Removed:'.$cach_file_d."\n";
	} else {
		echo 'Can not removed'.($cach_file_exist ? '(Error):':'(not Found):').$cach_file."\n";
	}
	
	if($debug) {
		// debug informations.
		echo "parameters:\n";
		foreach($params as $pkey => $param){
			echo '  "'.$pkey.'":'.$param['val']."\n";
		}
		echo "Cach file(Header):".$cach_file."\n";
		echo "Cach file(Data)  :".$cach_file_d."\n";
		echo "Cach file exist ? ".($cach_file_exist ? '(Error):':'(not Found):')."\n";
	}
 
} else {
	//	show usage
	echo 'Usage : php '.basename(__FILE__).' -c=%cache path% -l=%level% -u=%url% [-d]'."\n";
	echo ' ex.) '."\n";
	echo '   php '.basename(__FILE__).' -c=/var/cache/httpd -l=1:2 -u=http://example.com:80/sample.html?'."\n";
	echo '   "-d" options is debug mode. debug mode will not remove cache file.'."\n";
}


?>

ちょっと長くなりましたが、これは、nginxのやり方 とほぼ同じです。
ただ、34行目あたりから、58行目あたりまでが、Apache独自の処理で、32文字を20文字へ変換をかけています。
さらにディレクトリの文字列は、変換した20文字の先頭から取り出します。(nginxは後方から取り出します)残った文字列がファイル名になります。

ファイル名は、
・残った文字.header
・残った文字.data
の2つが存在し、.headerファイルにキャッシュキーや有効期限などの情報が出力されています。

一応、念のためにキャッシュファイルの中の指定されたURLキー情報が存在するかを確認してから削除しています。

上記の exmaple.com の例をこのphpスクリプトで実行すると以下のようになります。
ここでは、このphpスクリプトのファイル名を rm_cache.php としています。

$ php rm_cache.php -c=/tmp/cache -l=1:1 -u=http://exmaple.com:80/?
Removed:/tmp/cache/K/J/yoYNk2uot3Lia4URvdmw.header
Removed:/tmp/cache/K/J/yoYNk2uot3Lia4URvdmw.data
ディレクトリの階層の設定が、nginxの設定方法に合わせているので、Apacheの設定イメージとちょっと異なります。
...
CacheDirLevels 2
CacheDirLength 1
...
このように設定されている場合、 CacheDirLevels : ディレクトリの階層数なので、2階層までディレクトリを作成するという意味になります。
CacheDirLength : ディレクトリ名の文字列の長さなので、ディレクトリ名は1文字という意味になります。
つまり、1文字のディレクトリが2階層ということで、
-l=1:1
となり、それぞれの数値は、
1階層目ディレクトリの文字数:2階層目ディレクトリの文字数
ですから、それぞれ1文字という意味になります。


いかがだったでしょうか?
正直、Apacheのキャッシュは面倒です。
最近では、キャッシュを使う場合は、ほとんどがNginxを利用することが多いです。このキャッシュの取り扱いと不具合の多さから、Apacheを敬遠する方も多いのではないかと思います。
また、単純にキャッシュを使いたいなら、Squidなどのメジャーなサーバーもありますから、あえてApacheを使うという選択は、少ないのかもしれませんね。そのためのあってか、Apacheのキャッシュ系の記事は少ないです。
ご利用のブラウザは、広告ブロック(AdBlockなど) が適用となっていませんか?
このサイトでは、コンテンツの一部が非表示、あるいは、コメント、お問い合わせの投稿ができない検索ができないことがあります。


関連記事 :

nginx でリバースプロキシ、FastCGIキャッシュのキャッシュを削除する方法をまとめて解説してみた

nginx でリバースプロキシのキャッシュを削除する方法は、一応、色々な方法があります。 Nginx をリバースプロキシ(キャッシュ) ...

Apacheのキャッシュ(mod_cache,mod_disk_cache)を使ってみる

キャッシュ機能あるのは、Nginxだけではありません。 Apacheにもあります。 Apacheでキャッシュ機能を利用するには、mod_ca ...

Apacheのキャッシュ(mod_cache、mod_disk_cache)+Wordpressの注意点

ここまでに、Apacheのキャッシュ(mod_cache,mod_disk_cache)について、記事を書いてきました。 Apache ...

Squid でキャッシュを削除する方法をまとめて解説してみた

Squidをリバースプロキシとして使ってみた では、Squidによるリバースプロキシの設定について書きました。 そこでは、キャッシュされたファ ...

Debian(Ubuntu 12) で Dotdeb から最新のnginx をインストール、php-fprm を使ってphpを動かしてみる

Debian (Ubuntu 12) で Dotdeb から最新のPHP , MySQL をインストールする の続きで、今回は、最新のnginx ...



コメントを投稿 :

お名前 *

メールアドレス *
( メールアドレスが公開されることはありません。)

サイトアドレス

コメント *

* 印の項目は、入力が必要な項目です。




最近投稿の記事

[ 画像提供元 : Amazon ] 先日、1TBのディスクの入れ替え時にバックアップをとろうとディスクコピーを行いました。 その際 ...

Windows で Linux ファイルシステム Ext4 のディスクをマウントするには? Ext3Fsd が、おそらく、最も簡単なツール ...

今回は、Windows で Compass を使ってみました。 Compass とは、 Sass(サス、Syntactica ...

今回は、Anti Adblock を使ってみました。 Anti Adblock とは、 そもそも Adblock という ウェブ ...

デスクトップ環境でない サーバーで、Webページのキャプチャー画像をコマンドで撮る には、wkhtmltoimage, CutyCapt ...


さくらのVPS 全プラン リニューアルです。(石狩(北海道)も選択可)


root権限ありで ¥685 / 月 ~ と非常にリーズナブルな CPU 1(core)の 512 プランから、 最高 CPU 10(core), メモリ 32(GB), SSD容量 800(GB) までとプランが充実。
ディスクは、SSDとHDDの選択が可能になった他、データセンターは人気の東京、石狩(北海道)となりました。

また、どのプランでも好きなOSが選べます
( CentOS, Fedora, Scientific Linux, FreeBSD, Ubutu, Debian )

管理人もおすすめのVPSです。
試用期間がありますから、一度、お試しを!!

詳しくは、http://vps.sakura.ad.jp/さくらのVPSのサイトへ へどうぞ!!

カテゴリ


Serverman@VPS 完全1ヶ月無料 キャンペーン実施中です。


Serverman@VPS 完全1ヶ月無料 キャンペーン実施中です。
最近、スワップにも対応した Serverman@VPS は、かなりリーズナブルかもです。

  • メモリ1GB~2GBのEntryプラン :月額:490円
  • メモリ2MB~4GBのStandardプラン :月額:980円
  • メモリ4GB~8GBのProプラン :月額:1,980円

新規申し込みで1ヶ月間完全無料となるキャンペーンを実施中です。
Serverman@VPSの特徴は、安さとIPv6対応です。また、初期設定費0円もポイントです。

IPv6でちょっと遊んでみたい方には、おすすめかもしれませんね。最低利用期間もありませんから、気に入らないときは即解約もできます。

Serverman@VPSの詳細については、 http://dream.jp/vps/ Serverman@VPSのサイトへへどうぞ。



KVM採用 ConoHa VPSは、時間単位で借りれる便利なVPSです。


ConoHa VPS は、初期設定費0円最低利用期間無し時間単位で清算可能、 さらに、Web APIを使って自動化を図ることもできる便利なVPSです。

海外サーバー設置も可能で、ローカル接続にも対応と、かなり、機能豊富なサーバーです。

新規ユーザ登録で、クーポンもらえますから、まずは、お試しですね。

ConoHa VPSの詳細については、
http://www.conoha.jp/ へどうぞ。

KVM採用 お名前.com VPS(KVM) 2G プラン 初期設定費無料 キャンペーン 実施です。


メモリ2GBプラン CPU:3core、Disk:200GB
月額:1,153円から (初期設定:1,680円0円)

さくらのVPSがリニューアルされてもなんのその。
1GBメモリ / 2Core を ¥834 – の格安価格で提供中です!
間違いなくスペックからすると割安感ありです。
年間割引時の途中解約で返金がないのは、 ちょっと残念ですが、それでもこの割安感は魅力です。

まずは、お試しですね。

お名前.com VPS(KVM)の詳細については、
http://www.onamae-server.com/vps/ へどうぞ。(お試し期間が15日あります。)



  • ソーシャルブックマーク

  • はてなブックマークへ追加するはてな登録数
ページトップへ
Time : 0.2673 [s]