Cache::FileCacheのHowto
Cacheの実装として、ローカルのファイルシステムを使うもの。使ってみての所感をまとめたい。
導入により享受できる恩恵
- 当然ながら、DBへの負荷を減らせる
- ファイルなので複数プロセスで共有可能
- ローカルにあるのでネットワークトラフィック発生しない
注意すべき点
ファイルI/Oを意識する必要がある
key-value的な発想で使うとSQLより遅くなることもありえる。
たとえば新着日記を100件キャッシュしておこうと思ったときに、
日記IDをkeyにしてしまうのはNGである。このケースだと100回のFile I/Oが発生するためである。
最も効率的にやるには新着日記100件をハッシュリファレンスに入れて、丸っとキャッシュするのがよい。
これであれば、読み出しが1回で済む。
ベンチマーク(set)
use Cache::FileCache; use Benchmark; my $fcache1 = new Cache::FileCache({ namespace => 'test1'}); my $fcache2 = new Cache::FileCache({ namespace => 'test2'}); sub set1 { $fcache1->set($_, $_) for (1..100); } sub set2 { my $ref_hash; $ref_hash->{$_} = $_ for (1..100); $fcache2->set('all', $ref_hash); } timethese(100, { 'set1' => 'set1()', 'set2' => 'set2()', }); Benchmark: timing 100 iterations of set1, set2... set1: 12 wallclock secs ( 5.84 usr + 5.98 sys = 11.82 CPU) @ 8.46/s (n=100) set2: 0 wallclock secs ( 0.07 usr + 0.07 sys = 0.14 CPU) @ 714.29/s (n=100)
ベンチマーク(get)
use Cache::FileCache; use Benchmark; sub get1 { for (1..100) { $fcache1->get($_); } } sub get2 { my $ref_hash = $fcache2->get('all'); for my $key (keys %$ref_hash) { $ref_hash->{$key}; } } timethese(100, { 'get1' => 'get1()', 'get2' => 'get2()', }); Benchmark: timing 100 iterations of get1, get2... get1: 8 wallclock secs ( 2.75 usr + 5.48 sys = 8.23 CPU) @ 12.15/s (n=100) get2: 0 wallclock secs ( 0.04 usr + 0.08 sys = 0.12 CPU) @ 833.33/s (n=100)
まとめ
- Cache::FileCache使うなら、欲しい結果を丸っとキャッシュするのがGood.
- 決してKey-Value Storageのイメージで使わないこと