Kenichi Maehashi's Blog

脳内コアダンプ

RSS
Category: Linux
ちょいと使いたくなった。

プロトコルと設定

プロトコルは TCP / UDP のポート 11211 が標準。テキストベースなので、telnet でお話しすることもできます。
$ telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
version
VERSION 1.4.5
quit
Connection closed by foreign host.
詳しくは memcachedプロトコルについて などが参考になりました。

UDP で繋いだときのプロトコルは謎 (nc -u localhost 11211 してみたけどよく分からない)。オプション -U 0 で UDP で待ち受けなくなるようです。あと、必要であれば SASL 認証ができるらしい... ですが lo のみバインドさせておくのが無難ですね。

設定変更。稀に /etc/rc.d/init.d/memcached を直接編集することを推奨する記事がありますが、RHEL 系では /etc/sysconfig/memcached を編集しましょう。
PORT="11211"
USER="nobody"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 127.0.0.1 -U 0"

Perl から使う

というわけで、超ナイーブに使ってみます。単語帳から単語を中間一致検索します。
#!/usr/bin/perl

use strict;
use warnings;
use utf8;

use Fcntl;
use Time::HiRes qw/gettimeofday tv_interval/;
use Cache::Memcached;

my $memd = new Cache::Memcached {
'servers' => ["127.0.0.1:11211"]
};

sub main() {
my (@words, @results);
my ($begin, $cost);
my $query = $ARGV[0] || die "No query given!\n";

sysopen(my $fh, '/usr/share/dict/words', O_RDONLY);
@words = <$fh>;
close($fh);

$begin = [gettimeofday];

my $results_ref = search_word(\@words, $query);
@results = @$results_ref;

$cost = tv_interval($begin);

foreach my $result (@results) {
print "Result: $result\n";
}
print STDERR "Query: $query ($cost sec.)\n";
}

sub search_word(@$) {
my $words_ref = shift;
my $query = shift;
my $result_ref;
my @result;

$result_ref = $memd->get($query);
if (! defined $result_ref) {
$result_ref = linear_search($words_ref, $query);
}
@result = @$result_ref;
return \@result;
}

sub linear_search(@$) {
my $words_ref = shift;
my $query = shift;
my @words = @$words_ref;
my @result;
foreach my $word (@words) {
chomp $word;
if ($word =~ /$query/) {
push(@result, $word);
}
}
$memd->set($query, \@result);
return \@result;
}

main();
モジュールが勝手にシリアライズ・デシリアライズをやってくれるので、難しいことを考えなくていいのが嬉しい。

実行してみると、
$ perl search.pl ab > /dev/null
Query: ab (0.291347 sec.)
$ perl search.pl ab > /dev/null
Query: ab (0.046976 sec.)
# service memcached restart
Shutting down Distributed memory caching (memcached): [ OK ]
Starting Distributed memory caching (memcached): [ OK ]
$ perl search.pl ab > /dev/null
Query: ab (0.2867 sec.)
$ perl search.pl ab > /dev/null
Query: ab (0.045132 sec.)
ということで、2 回目からはすごく速くなります (memcached を再起動するとリセットされます)。いい感じ。

Comments

Leave Yours...
Name:
E-mail / URL (optional):
Comment:
Are You Robot?: