キャッシュの用途の問題で、memcachedではないキャッシュを使おうと思って色々調べたのだけど、やっぱり管理面の容易さを考えてTokyoTyrantかなぁってことで、試してみた。



Pecl::Memcached使ったら嵌った。

TokyoTyrantはmemcachedのインターフェイスも採用しているので、クライアントがそのまま流用できる。小さなデータで試したところ問題なく動いたので、そのまま本番データを流し込んでみたらばどうも上手くデータが返ってこない。なぜだ。

色々調べてみたところ、どうやら、クライアントとしてPecl::Memcachedを使っていたのが良くないらしい。Pecl::Memcachedはデフォルトで一定サイズ以上(デフォルトでは100バイト以上)のデータを圧縮してくれるのだけど、どうも取り出すときに解凍してくれない。圧縮されたまま。memcachedとして使えば問題ないので、互換インターフェイスの問題なんだろう。そーなのかー。



で、結局、NET_TokyoTyrantを使うことにした。

圧縮の設定を切っちゃうとか、Pecl::Memcacheを使うとか、あれこれやっても良かったのだけど、要するに互換インターフェイスよりネイティヴの方を使った方が良ってことじゃね?と思ったので、PEARのNET_TokyoTyrantをインストールしてみた。

Net_TokyoTyrantとは?
PurePHPで書かれた、TokyoTyrantのネイティブなインターフェースを叩くライブラリです。
memcache互換のインターフェースなどとは違い、TokyoTyrantのLUA拡張などTokyoTyrant本来の機能をほぼすべて使えるというのが特徴で
 
インストールはpearのchannelにopenpearを追加して、β版であることに気をつけつつインストールしてやるだけ(詳しくは上記エントリ参照)。


実際の使用法については、以下を参考に。

Tokyo Tyrant: network interface of Tokyo Cabinet
Tokyo TyrantによるHAなセッションストレージ 2 PHPから利用する篇 - Webと何かとその近所

サンプルコード

$tt = new Net_TokyoTyrant();
$tt->connect('localhost', 1978);
$tt->put('key', 'value');
echo $tt->get('key');   // value


というわけで利用は非常に簡単。
細かい計測はしていないけれど、体感でのパフォーマンスも悪くない。



ただし…有効期限は設定できない。

これはちょっと面倒。

本当は、この辺りを参考にしてきちんとTokyoTyrantに削除させるべき何だろうけど、

Fundamental Specifications of Tokyo Tyrant Version 1 - Lua Extension

さぼって、こんな風にしてみた。

サンプルコード(有効期限)

class MyTokyoTyrant {
...
  public function set($key, $value, $exp=0)
  {
    return $this->tt->put($key, serialize(array(
        'd' => $value,
        'expr' => time() + $exp
      )));
  }
  public function get($key)
  {
    $value = unserialize($this->tt->get($key));
  //expr
    if($value['expr'] <= time()):
      $this->delete($key);
      return false;
    endif;
    return $value['d'];
  }
  public function delete($key)
  {
    return $this->tt->out($key);
  }
...
}


つまりデータに有効期限を含めて取得時に参照するようにしてみた。getしないと有効期限がわからないという点で上手くないけれど、一応は動いてるっぽい。厳密な有効期限を求められるような用途ではなく、定期的に更新されればよいという程度の話なので、これでいいかな。

ちなみに、putするときの値はstringじゃないと上手く入らない。Memcachedは対応してくれるし、そんなコードを見かけた気もしたのでarrayを入れたら出てきた値は「Array」でちょっと笑った。



問題があればまた修正の予定で。