App Engineでのカウンタ

http://code.google.com/appengine/articles/sharding_counters.htmlに面白い記事を見つけたのでまとめておく.

複数のWebアプリケーションインスタンスがカウンタを共有することを考える.当然カウンタはデータベース上におき,トランザクション内でアトミックに読み出してインクリメントし,書き込む必要がある.しかしインスタンスの数が増えると衝突の可能性が増加し,性能が低下する.

これに対する方法として,この記事ではsharded counterという方法を提案している.ちなみにshard はカケラとかウロコとか言う意味で,私の辞書には動詞としての用法は載っていなかったが,なんとなく意味はわかる.

この方法では,カウンターを複数(たとえば20)に分割する.インクリメントするときには分割されたカウンターの一つをランダムに選択してインクリメントする.読み出すときには,分割されたカウンターの値を積算する.これは,App Engineのデータベースは読み込みに関してはほとんどの場合はキャッシュしていることになるので非常に高速であることを利用している.

さらに,分割されたカウンタの生成自体をlazyにすることによって動的にカウンターの数を増加させることを可能にしている.

この方法は,いろいろと応用が効きそうだ.