memcachedやってみた2
memcachedやってみた1 - Perl日記の続き。
じゃあPerlで接続してみる。
CPANからCache::Memcached::Fastをインストールして使う。
#!/usr/bin/perl # test.pl use strict; use warnings; package Memcached; use base qw/Cache::Memcached::Fast/; my $cache; sub new { my $class = shift; $cache ||= $class->SUPER::new( {servers => ['127.0.0.1:11211']} # memcached接続情報 ); return $cache; } package main; my $mem = Memcached->new(); my $key = 'myid'; my $value = 'rightgo09'; $mem->set($key, $value); print $mem->get($key), "\n";
% ./test.pl rightgo09
できた。
また、set()メソッドにはオプションの第3引数で有効期限(秒)が設定できる。
my $mem = Memcached->new(); my $key = 'myid'; my $value = 'rightgo09'; my $expire = 10; # 10秒保存 $mem->set($key, $value, $expire); print $mem->get($key), "\n"; sleep 5; print $mem->get($key), "\n"; sleep 6; print $mem->get($key), "\n";
% ./test.pl rightgo09 rightgo09
OK。
次はどのくらい早くなったのか、mysqlと比較しようと思ったけれど、いろいろ設定いじりすぎて今動かないのでDBD::CSVで代用。
1〜10までの値をMD5_hexに変換して格納し、取得速度を比較。
#!/usr/bin/perl # memcached_bench.pl use strict; use warnings; use Benchmark qw/timethese cmpthese/; package Memcached; use base qw/Cache::Memcached::Fast/; my $cache; sub new { my $class = shift; $cache ||= $class->SUPER::new( {servers => ['127.0.0.1:11211']} # memcached接続情報 ); return $cache; } package main; use List::Util qw/shuffle/; use Digest::MD5 qw/md5_hex/; use DBI; my $dbh = DBI->connect("DBI:CSV:f_dir=testdb") or die "Cannot connect: " . $DBI::errstr; $dbh->do("CREATE TABLE test_table (id INTEGER, hex CHAR(64))") or die "do: " . $dbh->errstr(); my $sth = $dbh->prepare('INSERT INTO test_table VALUES (?, ?)') or die "prepare: " . $dbh->errstr(); my $mem = Memcached->new(); # Key-Value Store my $max = 10; for my $id (1 .. $max) { my $md5_hex = md5_hex($id); $sth->execute($id, $md5_hex) # DBD::CSV or die "execute: " . $dbh->errstr(); $mem->set($id, $md5_hex); # Memcached } my $val_by_csv; $sth = $dbh->prepare('SELECT hex FROM test_table WHERE id = ?') or die "prepare: " . $dbh->errstr(); my $val_by_memcached; # Benchmark cmpthese( timethese( 10_000, { 'DBD::CSV' => sub { for my $id (shuffle(1 .. $max)) { $sth->execute($id) or die "execute: " . $dbh->errstr(); $sth->bind_columns(\$val_by_csv) or die "bind_columns: " . $dbh->errstr(); $sth->fetch() or die "fetch: " . $dbh->errstr(); } }, 'Memcached' => sub { for my $id (shuffle(1 .. $max)) { $val_by_memcached = $mem->get($id); } }, }, ) ); $dbh->disconnect(); __END__
% ./memcached_bench.pl Benchmark: timing 10000 iterations of DBD::CSV, Memcached... DBD::CSV: 79 wallclock secs (75.81 usr + 2.91 sys = 78.72 CPU) @ 127.03/s (n=10000) Memcached: 14 wallclock secs ( 1.19 usr + 2.88 sys = 4.07 CPU) @ 2457.00/s (n=10000) Rate DBD::CSV Memcached DBD::CSV 127/s -- -95% Memcached 2457/s 1834% --
うわはやい。
やっぱりCSVファイルからなんかじゃ比べものにならないな。
ちなみに使用マシンのスペックは、
- 2.1 GHz Intel Core 2 Duo
- 4GB 667MHz DDR2 SDRAM
- SSD 1.5ギガビット(って書いてあった)
最初は$maxを500にしてやったんだけど、DBD::CSVの方が30分経っても終わらなかった。
Memcachedだけにしてやったら48秒で終わった。
でもまあここまでならハッシュでもできる話ではある。
(メモリ上に残しておく、ということはできないけれど)
今度はこれをどう使えばいいか考えてみたい。
ミーハーだなあ僕。