読者です 読者をやめる 読者になる 読者になる

mod_mem_cache のはまりどころ?

Apache 2.2.4 でmod_mem_cache を導入し、
以下のような設定で動作させている場合

<IfModule mod_mem_cache.c>
  CacheDefaultExpire 1800
  CacheMaxExpire 1800
  CacheIgnoreCacheControl On
  CacheIgnoreNoLastMod On
  CacheEnable mem /
  MCacheSize 256000
  MCacheMaxStreamingBuffer 64000
  MCacheMaxObjectSize 64000
  MCacheMinObjectSize 1
  MCacheRemovalAlgorithm GDSF
</IfModule>

ab などででキャッシュの効果を確認してみると、
パフォーマンスが大幅に向上しているのが分かる。
が、この設定ではキャッシュの有効期限を過ぎてから悲惨な目にあう。
キャッシュの有効期限を過ぎたあとは、アプリケーションサーバから
最新のコンテンツを「毎回」取得してしまうのだ。
# 有効期限を10秒などと指定してみると、すぐに確認できる。
これではmod_mem_cache を導入した意味がほとんど無い。


いろいろと試してみたところ、キャッシュの有効期限を過ぎても
キャッシュ(および付帯情報)がメモリからすぐに削除されるわけでは無いようだ。

MCacheSize 256000

のように、極端に大きなサイズを指定している場合には
(有効期限の切れた)コンテンツが大量にキャッシュに残ってしまうのでは無いだろうか。

MCacheSize 64

とした場合、異なる二つのコンテンツを交互に取得することで
キャッシュが正常に更新されることが確認できた。
これは、キャッシュに使われるメモリの最大量をあっさりと超えるため
(有効期限の過ぎた)コンテンツをキャッシュから追い出し、
新しいキャッシュを生成しなおすためだろう。
MCacheSize を調整することで(あるいは、MCacheMaxObjectCount を用いることで)
うまく動かすことも可能だが、キャッシュを十分に活かすことはできない。


では、mod_disk_cache はどうなっているのかと思い

<IfModule mod_disk_cache.c>
  CacheDefaultExpire 1800
  CacheMaxExpire 1800
  CacheIgnoreCacheControl On
  CacheIgnoreNoLastMod On
  CacheRoot /usr/local/apache2/cache
  CacheEnable disk /
  CacheDirLevels 5
  CacheDirLength 3
  CacheMaxFileSize 64000
  CacheMinFileSize 1
</IfModule>

こんな設定で試してみたところ、

  1. 有効期限を過ぎるまではキャッシュを返却
  2. 有効期限を過ぎたらアプリケーションサーバから最新コンテンツ取得
  3. 再び有効期限を過ぎるまではキャッシュを返却

と、期待どおりの結果となった。


パフォーマンスは若干メモリキャッシュより劣っている気もするが
キャッシュを使用していなかったときと比べれば誤差の範囲と言える。


mod_disk_cache の不便な点は、使われなくなったキャッシュがいつまでも
ディスクに残ってしまうところだが、簡単なシェルスクリプトとcron で
どうにでもなるので、大きな問題にはならない。


ところで、上記のmod_mem_cache の挙動は仕様どおりなのだろうか。
バージョンを変えたらあっさりmod_disk_cache と同じように動いてくれたりしないかな。


なお、キャッシュのヒット率やキャッシュされてからの経過時間は
http://qb5.2ch.net/test/read.cgi/operate/1130482779/415n-416

415 :ひろゆき@どうやら管理人 ★ :2007/01/04(木) 19:38:09 ID:???0 ?S★(102333)
mod_cacheとmod_proxyを併用してる場合のキャッシュのヒット率って
どこを見るとわかるんでしょうか、、、


416 : 株価【1600】 ▲▲▲▲ ◆cZfSunOs.U :2007/01/05(金) 00:10:58 id:tB3xz27F0
>>415 mod_cache にはヒット率を記録する仕組みはなさそうですね.
調べるとすれば,アクセスログで %{Age}o つまり Age レスポンスヘッダを記録して,
Age ヘッダの有無の比率から算出するとかかなぁ......

この方法で確かめることができる。