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

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

ロックを使わずにmemcacheで値を受け渡す方法

memcacheに対するロックを書かずに、リングバッファみたいなキューを作って値を受け渡しする方法が以下の記事で紹介されてました:

Memcache lockless queue implementation

値を書き込むときはこんな感じ。例のincrementメソッドでアトミックに連番を取得して、それをキーに値を書き込みます。この連番がキューの先頭になります。

    def __nextWriteCounter(self):
        counter = memcache.incr(self.writeCounter)
        if not counter:
            memcache.set(self.writeCounter, 0)
            counter = 0
        return counter

一方、値を読み込む時は、キューの最後を示す連番で値を読み、その後incrementメソッドで連番をひとつ増やします。

    def read(self):
        counter = self.__currentReadCounter()
        msg = memcache.get(self.name + str(counter))
        #logging.debug("attempt to read from %s" % (self.name + str(counter)))
        if msg:
            memcache.incr(self.readCounter)
            memcache.delete(self.name + str(counter))
            logging.debug("read from %s" % (self.name + str(counter)))
            return msg
        return None

この方法なら、まったくロックせずに値の受け渡しができますね。

もっとも、値を単純に受け渡すだけならこれでOKですが、例えば「既存の値を読み取り、それに基づいて計算して、その結果で値を更新する」みたいなトランザクションを実行するには、やっぱり何らか(pessimistic/optimistic)のロックをmemcacheの値にかける必要があると思います。たぶん。。

あわせて読みたい
Memcached Lockless Queue