nDiki : Cache::Memcached

Cache::Memcached

キャッシュシステム Memcached Perl クライアント API

パッチ

Cache::MemcachedPerl 5.005_03 で使用するためのパッチ。

Cache-Memcached-1.x ディレクトリのある場所で

 patch -p0 < パッチ

スポンサード リンク

2004年1月12日 (月)

[ Perl ] Memcached を使ってみる

WiKicker の高速化に Memcached が使えないかいろいろいじってみる。 評価は今のところ「微妙」。 Memcachedメモキャッシュを提供するデーモンプログラムで、キーと値の配列を記憶しておいてくれる。 Slashdot でも使っているらしい。

ホスティングサービスのサーバ(FreeBSD 4.4-RELEASE)に入れてみる。

Memcached 1.1.10

依存している libevent と一緒にビルドしてインストール

 cd /tmp
 wget http://www.monkey.org/~provos/libevent-0.7c.tar.gz
 tar zxvf libevent-0.7c.tar.gz
 cd libevent-0.7c
 ./configure
 make
 cd ..
 wget http://www.danga.com/memcached/dist/memcached-1.1.10.tar.gz
 tar zxvf memcached-1.1.10.tar.gz
 cd memcached-1.1.10
 CFLAGS='-L../libevent-0.7c -I../libevent-0.7c' ./configure --prefix=$HOME/local/memcached-1.1.10
 make
 make install

'-l' オプションがうまく動かない。

 bind(): Can't assign requested address
 failed to listen
 /PRE

指定しなくても動くのでとりあえず、よしとする。

ちなみに、EVENT_SHOW_METHOD=1 の結果は以下の通り。

 $ EVENT_SHOW_METHOD=1 ./memcached
 libevent using: kqueue

Cache::Memcached 1.0.11

Perl 用の API モジュールを入れておく。 make test でこける。

 Your vendor has not defined Socket macro MSG_NOSIGNAL

use Socket qw(MSG_NOSIGNAL PF_INET SOCK_STREAM); のところ。 Solaris/*BSD だと駄目らしい。 CVS版だと解決されいるようなので、こちらを。

Cache::Memcached CVS

 cvs -d :pserver:anonymous@danga.com:/home/cvspub checkout wcmtools/memcached/api/perl

でとってくる。 こちらは Perl 5.005_03 という古いバージョンでいくつか問題。

 our $SOCK_TIMEOUT = 2.6;

のところの our は Perl 5.005_03 には無いので、use vars に置き換え。 use bytes も 5.005_03 に無いのでコメントアウト。

IO::Handle::blocking() も無い。

 sub my_blocking {
   my ($sock, $bool) = @_;

   my $old_flags = fcntl($sock, F_GETFL, 0)
       or die "Can't get flags for the socket: $!\n";

   if ($bool) {
       my $flags = fcntl($sock, F_SETFL, $old_flags | O_NONBLOCK)
           or die "Can't set flags for the socket: $!\n";
   }
   else {
       my $new_flag = $old_flags & ~O_NONBLOCK;
       my $flags = fcntl($sock, F_SETFL, $new_flag)
           or die "Can't set flags for the socket: $!\n";
   }
   return $old_flags & O_NONBLOCK;
 }

...でいいのかな? ささっと書いたんで一部バグっているかもしれないが、とりあえず代替しておく。

ちなみに Cache::Memecached の古い版、MemCachedClient-1.0.7 も試してみたけれどこちらも IO::Socket::INET が必要だったり面倒(なので、1.0.11 のパッチ当ての方をがんばった)。

スピード

うーん。思ったほど速くないな。 いや手元のLinuxだとかなり速いんだけれど、FreeBSD だとそうでもない。 Client側の問題が大きいようだ。 下手するとLinux BOX からADSL経由でキャッシュを読み込む方が、FreeBSD のローカルホストから読むより速かったりする。

どうも Socket の接続/切断まわりでもたついている感じである。 (無駄なはずなのだが)毎回 disconnect_all してしまった方が、Benchmark の値が良かったりするし。 接続 -> キャッシュ取得 -> 切断 で 0.6秒というのはちょっと遅すぎる。 もうちょっといじってみれば実用的な速度になるのだろうか?

スポンサード リンク
[ 1月12日全て ]

2004年1月14日 (水)

[ Perl ] Cache::Memcached

もう一度確認したら、昨日思っていたほどより遅くなかった。 また、CVS版では、Cache::Memcached の new オプションで select_timeout でちょっと大き目の値を指定してあげると(デフォルト 1.0)「selectがタイムアウト→ socket がクローズされる」事がなくなってそこそこいい速度が出るようになった。 ちなみに Cache::Memcached 1.0.11 にはまだこのオプションはない。

うん。これなら高速化に使えるかも。

[ 1月14日全て ]

2004年6月5日 (土)

[ WiKicker ] キャッシュまわりにバグ

Memcached まわりをいじったので、キャッシュ具合をテストしていたら変な現象が。 WikiPage が表示されるべきところに、検索結果が表示されている。 あれ?

ページの内容が表示されるところに検索結果が

WiKicker では WikiPage のレンダリング結果も検索結果もキャッシュしているが、それぞれ別のキャッシュキーになるようにしている (WiKickerのバージョンを $V とすると、'$V:h:ページ名' と '$V:s:検索語')ので混ざるはずがないんだけれどな。 キャッシュしているデータの形式も違うし。

最初は Memcached まわりのアップデートで不具合がでたのかと思ったが、戻しても変わらない。ということは、ずっと以前からこの問題が発生していたのか。 やば。 設定でニックネームを設定している(cookie に保存している)と、その Web ブラウザに対してはキャッシュ機能が働かないようになっているので発見が遅れてしまった。

で結局コードをチェックしてみたら「WikiPage 表示と検索結果表示の View クラスを同じにしていたため、検索結果のレンダリングが WikiPage レンダリング結果と同じ領域にキャッシュされる」という風になってしまっていた。 ということで誰かがページ名で検索するとそれがキャッシュされてしまい、ページを読もうとしてもキャッシュ破棄されるまで検索結果が表示されてしまうというひどい状況になっていたと。

修正。

キャッシュキーのバグ

Memcached の出力をチェックしていたら、たまにエラーが起きていることを確認。 Memcachedプロトコルをチェックしたら、キーには制御文字と空白は使えないとある。 Cache::Memcached を見たらキーはそのまま through するだけ。 ということでページ名に空白が含まれている場合などの時には、まずい事になっていたようだ。 こちらは、キーを自前でエンコーディング(ページデータベースファイル名の作成に使っている base64 の亜種)するように修正。

Cache::Memcached 1.13 の Perl 5.005_03 対応

WiKicker で使用しているキャッシュシステム Memcached 用の Perl API Cache::Memcached が新しくなっていたので、入れ換え。

1月に入れた時と同様、Perl 5.005_03 ではそのまま動かないので一部を修正。 前回はCVSスナップショット(Memcached.pm revision 1.8)に対する修正だったので手元で修正しただけだったが、今回はパッチも作っておく。

修正点は

  • our を使わないようにする。
  • fields::new を代替コードに。
  • IO::Handl::blocking を代替コードに。
  • use bytes を使わないようにする。

といったところ(WiKicker で使っているところのみ修正)。

以前は Use of uninitialized value がかなり出ていたのだが、 Cache::Memcached のコード自体が綺麗になったのかこれらも出なくなっていい感じ。

Memcached 1.1.11

Perl API (Cache::Memcached)のアップデートのついでに、Memcached 自体もアップデート

 cd /tmp
 wget http://www.monkey.org/~provos/libevent-0.8.tar.gz
 tar zxvf libevent-0.8.tar.gz
 cd libevent-0.8
 ./configure
 make
 cd ..
 wget http://www.danga.com/memcached/dist/memcached-1.1.11.tar.gz
 tar zxvf memcached-1.1.11.tar.gz
 cd memcached-1.1.11
 CFLAGS='-L../libevent-0.8 -I../libevent-0.8' ./configure --prefix=$HOME/local/memcached-1.1.11
 make
 make install
[ 6月5日全て ]

2004年7月31日 (土)

Cache::Memcached 1.14 の Perl 5.005_03 対応

1.14 が 7月27日にリリースされていたのでパッチ作成。 1.13 用のパッチがあたったのでそのままいけるかなと思ったが、テストしたところまたいくつかの非互換コードが増えていたのでそれらの修正を行う。

 tar zxvf Cache-Memcached-1.14.tar.gz
 cp -a Cache-Memcached-1.14 Cache-Memcached-1.14.orig
 patch -d Cache-Memcached-1.14 -p1 \
   < Cache-Memcached-1.13-5.005_03-20040605.diff
 find Cache-Memcached-1.14 -name '*.orig' -exec rm {} ';'
 emacs Cache-Memcached-1.14/Memcached.pm
 LC_ALL=C TZ=UTC0 diff -Naur \
   Cache-Memcached-1.14.orig Cache-Memcached-1.14 \
   > Cache-Memcached-1.14-5.005_03-20040731.diff

新規修正点は

  • Socket モジュールでのインポートで IPPROTO_TCP が追加になったところが実験環境でエラー。コードの中では利用していないので削除。
  • ChangeLog 中の下記のため @+ を使うようになったようだが、5.005_03 では定義されていないのでエラー(perl.*delta のどこにものっていないのでチェックに苦労。perlretut に言及があって Perl 5.6.0 から提供されるようになった事を確認)。Cache::Memcached 1.13 で行っている pos を使った処理に戻す。
 2004-07-19
         * don't use pos() because it doesn't seem to work in
           taint mode.  use $+[0] instead.  (Dave Evans <..@djce.org.uk>)

それからパッチの作り方を変更。patch の man の通り LC_ALL=C TZ=UTC0 にするのとオプションを -Naur を使うように。

また 1.14 から String::CRC32 が必要になった。

[ 7月31日全て ]

2006年2月10日 (金)

WiKickerMakefile.PLModule::Install ベースに

WiKicker には依存している Perl モジュールとして、必須なものとオプションなものがある。 必須なものは例えば Log::Log4perl など。 一方 Cache::MemcachedHTML::Scrubber などは、追加機能を使用したい場合のみ必要である。

一般的な Perl モジュールパッケージと同様、WiKicker では Makefile.PLExtUtils::MakeMaker を使っている。 必須な依存 Perl モジュールは PREREQ_PM に指定してあるが、オプションのものについては独自にチェックして警告をするにとどめていた。 しかしこれだと、オプションのものは CPAN.pm を使って自動的にインストールすることができない。

ということで検討した結果、Module::Install を用いることにした。 Module::Install を用いて Makefile.PL を作成すると、

などの機能が使えるようになる。

Module::Install の実行に必要なファイルはパッケージの inc ディレクトリ以下に自動的にコピーされ配布パッケージに含められるので、インストールする側はそのために余分なインストールを強いられることもない。

最終的に内部で ExtUtils::MakeMaker を使っているので、それの機能はほぼ全て使える。

Perl のバージョンも 5.004 から使えるとのことで、Perl 5.005_03 以上を対象としている WiKicker で使っても問題なし。

ということで、Makefile.PL をさらっと書き換え。

合わせて WiKicker に含まれていた実験的な機能を削除して、(オプションな)依存モジュールも減らすことにした。

次回のリリース版から、Module::Install ベースだ。

[ 2月10日全て ]

About Me

Naney Naney (なにい)です。株式会社ミクシィでマネージャー・プロダクトオーナーをしています。

nDiki1999年1月に始めたコンピュータ日誌を前身とする NaneyWeb 日記(兼パーソナルナレッジベース)です。ちょっとしたノートは nNote にあります。

follow us in feedly

※内容は個人的見解であり所属組織とは関係ありません。

月別インデックス
Process Time: 0.190348s / load averages: 0.83, 0.80, 0.80
nDiki by WATANABE Yoshimasa (Naney, Google profile)
Powered by DiKicker