Cache::Memcached::Fastを試す
Perlの新しいmemcachedクライアント「Cache::Memcached::Fast」がでていたので試してみた
結論から言うと、これは使えそう。
まず、C::M::Fastはmemcached-1.2.4でサポートされた、append, prepend, cas, gets, gets_multiをサポートする唯一のPerlクライアントです。また、常に問題となるCache分散にKetama consistent hashing algorithmをサポートしているためCacheの組み替えを最小限にしてCacheサーバの追加が行えます。
手元のベンチマークでは50%〜80%、処理によりますが300%以上高速化されてます
インストールは普通にCPANから行えます。ただし、memached-.1.2.4が動いていないとmake
testに失敗します。Cache::Memcahedとの互換性もあり、単純な入れ替えで使えるようです。
軽くベンチマークをとってみました。
ベンチマークのスクリプトはid:tokuhiromのスクリプトを拝借しました
use strict;
use warnings;
use Cache::Memcached::GetParserXS;
use Cache::Memcached;
use Cache::Memcached::Fast;
use Benchmark qw/cmpthese/;
my $n = 5000;
my $max = 500;
my @keys = map { "x" . $_ } 0..$max;
my $m = Cache::Memcached->new( +{ servers => ['127.0.0.1:11211'] } );
$m->enable_compress(0);
my $fast = Cache::Memcached::Fast->new( +{ servers => ['127.0.0.1:11211'] } );
$m->set( $_ => rand ) for @keys;
foreach my $num ( qw/1 5 10 100 500/ ) {
print "### $num\n";
my @keys = map { "x" . $_ } 0..$num;
cmpthese(
$n => +{
parser_xs => sub {
$m->get_multi(@keys);
},
fast => sub {
$fast->get_multi(@keys);
},
}
);
}
結果
$ perl memcached_bench.pl
### 1
Rate parser_xs fast
parser_xs 1241/s -- -80%
fast 6173/s 398% --
### 5
Rate parser_xs fast
parser_xs 1176/s -- -78%
fast 5263/s 347% --
### 10
Rate parser_xs fast
parser_xs 1567/s -- -63%
fast 4202/s 168% --
### 100
Rate parser_xs fast
parser_xs 557/s -- -56%
fast 1256/s 125% --
### 500
Rate parser_xs fast
parser_xs 178/s -- -41%
fast 299/s 68% --
テストに用いたマシンは、
OS: CentOS 4 ( kernel 2.6.9 )
CPU: Celeron 2.8GHz
Memory: 1GB
です
C::M::Fastのディストリビューションに含まれるcompare.plを動かしてみるとget_multi以外のベンチマークもとれます
以下はその結果
./script/compare.pl localhost:11211 100000
Benchmark: timing 100000 iterations of New add(40 bytes), Old add(40 bytes)...
New add(40 bytes): 27.5119 wallclock secs (12.44 usr + 6.34 sys = 18.78 CPU) @ 5324.81/s (n=100000)
Old add(40 bytes): 43.3037 wallclock secs (23.78 usr + 9.32 sys = 33.10 CPU) @ 3021.15/s (n=100000)
Rate Old add(40 bytes) New add(40 bytes)
Old add(40 bytes) 3021/s -- -43%
New add(40 bytes) 5325/s 76% --
Benchmark: timing 100000 iterations of New set(40 bytes), Old set(40 bytes)...
New set(40 bytes): 27.9549 wallclock secs (12.63 usr + 6.60 sys = 19.23 CPU) @ 5200.21/s (n=100000)
Old set(40 bytes): 43.8092 wallclock secs (23.68 usr + 9.47 sys = 33.15 CPU) @ 3016.59/s (n=100000)
Rate Old set(40 bytes) New set(40 bytes)
Old set(40 bytes) 3017/s -- -42%
New set(40 bytes) 5200/s 72% --
Benchmark: timing 100000 iterations of New replace(40 bytes), Old replace(40 bytes)...
New replace(40 bytes): 28.2981 wallclock secs (12.81 usr + 6.64 sys = 19.45 CPU) @ 5141.39/s (n=100000)
Old replace(40 bytes): 44.8797 wallclock secs (24.10 usr + 9.42 sys = 33.52 CPU) @ 2983.29/s (n=100000)
Rate Old replace(40 bytes) New replace(40 bytes)
Old replace(40 bytes) 2983/s -- -42%
New replace(40 bytes) 5141/s 72% --
Benchmark: timing 100000 iterations of New get, Old get...
New get: 22.8232 wallclock secs ( 9.93 usr + 6.15 sys = 16.08 CPU) @ 6218.91/s (n=100000)
Old get: 89.768 wallclock secs (63.76 usr + 17.16 sys = 80.92 CPU) @ 1235.79/s (n=100000)
Rate Old get New get
Old get 1236/s -- -80%
New get 6219/s 403% --
Benchmark: timing 1000 iterations of New get_multi(100 keys), Old get_multi(100 keys)...
New get_multi(100 keys): 1.65893 wallclock secs ( 1.02 usr + 0.19 sys = 1.21 CPU) @ 826.45/s (n=1000)
Old get_multi(100 keys): 2.60043 wallclock secs ( 1.92 usr + 0.29 sys = 2.21 CPU) @ 452.49/s (n=1000)
Rate Old get_multi(100 keys) New get_multi(100 keys)
Old get_multi(100 keys) 452/s -- -45%
New get_multi(100 keys) 826/s 83% --
Benchmark: timing 1000 iterations of New get x 100, New get_multi(100), Old get x 100, Old get_multi(100)...
New get x 100: 17.2965 wallclock secs ( 6.62 usr + 4.87 sys = 11.49 CPU) @ 87.03/s (n=1000)
New get_multi(100): 1.24405 wallclock secs ( 0.69 usr + 0.17 sys = 0.86 CPU) @ 1162.79/s (n=1000)
Old get x 100: 88.6322 wallclock secs (61.79 usr + 16.76 sys = 78.55 CPU) @ 12.73/s (n=1000)
Old get_multi(100): 2.33868 wallclock secs ( 1.72 usr + 0.24 sys = 1.96 CPU) @ 510.20/s (n=1000)
Rate Old get x 100 New get x 100 Old get_multi(100) New get_multi(100)
Old get x 100 12.7/s -- -85% -98% -99%
New get x 100 87.0/s 584% -- -83% -93%
Old get_multi(100) 510/s 3908% 486% -- -56%
New get_multi(100) 1163/s 9034% 1236% 128% --
Benchmark: timing 100000 iterations of New delete, Old delete...
New delete: 27.032 wallclock secs (13.17 usr + 6.53 sys = 19.70 CPU) @ 5076.14/s (n=100000)
Old delete: 37.7127 wallclock secs (20.63 usr + 9.39 sys = 30.02 CPU) @ 3331.11/s (n=100000)
Rate Old delete New delete
Old delete 3331/s -- -34%
New delete 5076/s 52% --
Tomash++
あと、Brian Akerのlibmemcachedを利用したTim Bunceのperl-libmemcachedに期待しています