スティルハウスの書庫の書庫

はてなダイアリーで書いてた「スティルハウスの書庫」を移転してきました。

memcacheとDatastoreでライトバック付きKVSをつくる

Datastoreの鬼門である集計関数の代わりのカウンター等を実装するとき、sharded counterより高速なものを求めると、「とりあえずmemcacheに書き込んで、cron/TQでDatastoreに非同期に保存する」ような仕組みがほしくなります。カウンターに限らず、「ライトバック付きKVS」があればいろいろな局面で便利そうです。

そこで以下のようなコードを実装しました。

  • get操作
    • キーでmemcacheを探して、値があればそれを返す
    • キーでDatastoreを探して、値があればそれを返す
    • nullを返す
  • set操作
    • キーと値をmemcacheに保存する
    • 「キーリスト」を取得する
    • 「キーリスト」にキーを追加してmemcacheに保存する
  • Cron/TQで呼ばれる保存処理
    • 「キーリスト」を取得して、Datastoreに保存する
    • すべてのキーについて、memcacheのエントリーをDatastoreに保存する
  • キーリストの取得
    • 「キーリスト」をmemcacheから取得する
    • なければDatastoreから取得する

キーの種類が固定なら簡単なのですが、不特定多数のキーに対応しようとすると「キーリスト」自体もライトバックで管理する必要があり、ちょっと面倒です。

このライトバック付きKVSですが、sharded counterと比べると、

  • 1桁くらい速いはず(数ms?)
  • トランザクショナルではない
  • memcache内容がDatastoreに保存されるまでに間が空くので、値が失われる可能性がある(Cronなら最大1分間、TQなら数秒?)

という違いがあります。トランザクショナルではないおおざっぱな値の保持用です。Javaでも早くTQサポートして〜。