« Params::TinyとHash::MultiValue、もしくは本物のTinyについて | メイン | Cache::Redisってのを書いたら意外と大変だった件 »

2013年5月26日

memcachedのflagsってのが何のためにあるのかっていう話

memcachedで値をセットするときに以下みたいな感じでセットするわけですが、 この<flags>ってのが何のためにあるのかいまいちよくわかってなかったわけです。

set <key> <flags> <exptime> <bytes>
<data>

で、Cache::Redis書いてた時にCache::Memcached::Fastの実装を見てたら、 あーこれ大事だわってなった。C::M::Fだと、ストアされているデータが

  • シリアライズされてるか否か
  • 圧縮されてるか否か
  • 文字列か否か

みたいな情報をこのflagsに持たせています。

C::M::Fはオブジェクトやリファレンスはシリアライズして、 単一スカラ(数値や文字列やバイナリ)はシリアライズせずに値をストアするように なってます。これはデフォルトのシリアライザであるStorableが単一スカラをシリアラ イズできないというのもありますし、単一スカラであればシリアライズしないほうが 情報が人間に読みやすいってのもありそうです。

その場合、例えばシリアライザがStorableの場合だと、memcachedから値を取得してき た値がバイナリだった場合、それはシリアライズした結果バイナリなったものなのか それとも、元からバイナリデータが突っ込まれていたのかがその値だけでは判別出来ません。 そこでflagsを見て判断するようになってるわけです。(具体的には0x1との論理積をとっている)

もう一つ例を出すと、シリアライザがJSONの場合、[1]っていうデータが入っていた として、それが配列なのか、文字列としての’[1]’なのかがそれだけだとわからないって話です。

一定サイズ以上の文字列を圧縮してストアするみたいなことも、C::M::Fはできるよう になっているので、そのへんの判別もflagsを見てやるようになっています。

値に対する最低限のメタ情報を値とは別に持たせられるようにしてあるのは 実用性を考えたいい設計だなーと思ったわけです。

Redisの場合だとそういう値とは別のメタ情報をもたせられるようにはなってないので (もちろんやりようは色々あるわけですが)、Cache::Redisを書く際にちょっと苦労した という話。その辺の話は次のエントリーで書きます。

投稿者 Songmu : 2013年5月26日 23:49