設計方針として「Memcached より先に FileCache を見るように」という話を聞いたので、「えー、それって性能的にどうなんだろうか?」と思い、簡単にベンチマークをとってみました。
環境としては、同一セグメント内のまったく別のホストに Memcached サーバを立てました。つまり、I/Oコストだけでなく通信コストなども含めての比較をしています。
ちなみに、このベンチのために、わざわざ memcached を入れるところから始めました。もちろん連休で時間があるからです。
ソース。
#!/usr/bin/perl -w use strict; use warnings; use utf8;
use Cache::FileCache; use Cache::Memcached::Fast; use Benchmark qw(:all);
our $c = 0;
my $count = 10000; my $compare = timethese( $count, { filecache => sub { $c = 0; my $cache = Cache::FileCache->new({ namespace => 'test', default_expires_in => 600, cache_root => '/tmp', }); my $data = $cache->get('key' . $c++); unless ( defined $data ) { $cache->set('key' . $c++, 'value'); } return $data; },
memcached => sub { $c = 0; my $cache = Cache::Memcached::Fast->new({ servers => ['192.168.50.102:11211'], }); my $data = $cache->get('key' . $c++); unless ( defined $data ) { $cache->set('key' . $c++, 'value'); } return $data; }, }, );
cmpthese $compare;
10000 回の R/W の結果はこちら。
Benchmark: timing 10000 iterations of filecache, memcached... filecache: 5 wallclock secs ( 4.55 usr + 0.76 sys = 5.31 CPU) @ 1883.24/s (n=10000) memcached: 7 wallclock secs ( 0.26 usr + 0.15 sys = 0.41 CPU) @ 24390.24/s (n=10000) Rate filecache memcached filecache 1883/s -- -92% memcached 24390/s 1195% --
なんと FileCache の圧倒的な勝利。ネットワークコストが大きかったのか、想定外の差が出て驚きました。冒頭の設計方針に一理あるということは分かりました。疑ってすみません。しかし何か根本的なところを間違っていそうな気もしなくはないなあ。
最近は、ディスクI/Oをとにかく敵対視する日々が続いていたけれども、先入観というか偏りのある発想になってしまってはいけないですね。反省。
ちなみに、「じゃあ Memcached やめて FileCache を積極的に使っていこうぜ!」とはもちろんならないです。それぞれの環境に応じて求められるものは変わってくるし、分散であったり failover しやすかったりという優位性があるので、それなりの規模で総合的に判断すると、 Memcached に軍配が上がるんではないでしょうか。逆に言えば、スタンドアローンだったり、Webサーバ1台・DBサーバ1台みたいな環境であれば、FileCache の方がメリットが大きそうですね。
ベンチの見方を盛大に誤っていまして、上記でまったく逆の考察をしていますが、誤爆です。やはり超圧倒的に Memcached が高速でした。wallclock secs を見ていたのですが、普通に秒間処理で測るんですよね。10倍以上の性能差です。
なので、考察としては、よほどネットワークコストが大きいとか、ディスクI/Oに対してメモリが不足しているとか、共用環境で memcached 立てられないといった限定的な環境以外では、FileCache の出番は無いということです。今回の検証は HDD でしたが、SSD にしても改善される性能は 2-3 倍程度でしょうから、Memcached の優位性は変わらないでしょう。