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に期待しています