FileCache と Memcached を比較する

設計方針として「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 の優位性は変わらないでしょう。

CentOS に memcached をインストールする

以前は yum でサクッとインストールできたと記憶しているのだけど、今は yum でインストールできないようなので、ソースからインストールしました。手間がかかったので、次回へのメモとして、ログを残しておきます。

まず、memcached が使うイベント通知APIの libevent のバージョンを確認。

# rpm -q libevent
libevent-1.1a-3.2.1

1.1系と古いので、新しいものを入れます。ソースは公式サイトから、安定版のうち最新のものを持ってきます

# cd /usr/local/src
# wget http://www.monkey.org/~provos/libevent-1.4.13-stable.tar.gz
# tar xvfz libevent-1.4.13-stable.tar.gz
# cd libevent-1.4.13-stable
# ./configure --prefix=/usr/local/libevent
# make
# make install

続いて、 memcached をインストールします。ソースは公式サイトから。

# cd /usr/local/src
# wget http://memcached.googlecode.com/files/memcached-1.4.5.tar.gz
# tar xvfz memcached-1.4.5.tar.gz
# cd memcached-1.4.5
# ./configure --with-libevent=/usr/local/libevent/
# make
# make install

起動コマンドを作ってサービス登録します。といっても、そのままコピーですが。キャッシュ容量やポート番号を変えるなどしたい場合は、このスクリプトのなかをいじりましょう。

# cp /usr/local/src/memcached-1.4.5/script/memcached.sysv /etc/rc.d/init.d/memcached
# chkconfig --add memcached
# chkconfig --list memcached

用意が整ったところで、起動します。

# /etc/rc.d/init.d/memcached start

ここで、起動せずに次のようなエラーが出ることがあります。

memcached: error while loading shared libraries: libevent-1.4.so.2: cannot open shared object file: No such file or directory

今回は libevent を /usr/local/libevent にあるものを使うため、ldconfig してあげなければいけませんでした。

# echo "/usr/local/libevent/lib" > /etc/ld.so.conf.d/libevent.conf
# ldconfig

このあと起動すれば、問題なく立ち上がると思います。動作確認をします。

$ telnet localhost 11211
stats
STAT pid 11440
STAT uptime 71
STAT time 1272779578
STAT version 1.4.5
STAT pointer_size 32
STAT rusage_user 0.000000
STAT rusage_system 0.010000
STAT curr_connections 10
STAT total_connections 11
STAT connection_structures 11
STAT cmd_get 0
STAT cmd_set 0
STAT cmd_flush 0
STAT get_hits 0
STAT get_misses 0
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 7
STAT bytes_written 0
STAT limit_maxbytes 67108864
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT bytes 0
STAT curr_items 0
STAT total_items 0
STAT evictions 0
STAT reclaimed 0
END

stats と打つとステータスが、バーっと流れるので確認しましょう。プロンプトを抜けるときには、いつもどおりで quit と打てば OK。

最近セットアップを自動化しているせいで、こうしてソースから入れるのは2年ぶりくらい。ldconfig とか忘れてしまっていて、やり方を思い出すのに、ムダに時間かかってしまいました。うーむ。

以上、おつかれさまでした。


最新エントリー
FileCache と Memcached を比較する
CentOS に memcached をインストールする
あわせて読みたいブログパーツ