4

redis データベースを操作するために python パッケージ (redis-py) を使用しています。Redis でハッシュのキーと値を設定するクライアントがたくさんあります。ハッシュが存在する場合にのみキーと値を設定してほしい。ハッシュが存在しない場合、キーと値を設定するとハッシュが作成されますが、これは私がやりたいことではありません。

redis-py ページ (https://github.com/andymccurdy/redis-py) で、著者はクライアント側でアトミック操作を行う方法を提案しました。だから私は同様の関数を書きました:

    with r.pipeline() as pipe:
        while True:
            try:
                pipe.watch("a_hash")
                if pipe.exists("a_hash"):
                    pipe.hset("a_hash", "key", "value")                  
                break
            except redis.WatchError:
                continue
            finally:
                pipe.reset()

ただし、これは機能しないようです。別のクライアントからハッシュを削除した後も、このハッシュはこのコードによって作成されるため、このコードはアトミック操作ではないと思います。誰かがこのコードの問題を特定するのを手伝ってくれますか? または、この目的を達成するためのより良い方法はありますか?

あなたの助けに感謝!

4

1 に答える 1

4

Redis documentationで説明されている WATCH/MULTI/EXEC ブロックの定義を読むことをお勧めします。

このようなブロックでは、MULTI と EXEC の間のコマンドのみが実際にアトミックに処理されます (条件付きで、ウォッチに応じて全か無かのセマンティックで)。

あなたの例では、 EXISTS および HSET コマンドはアトミックに実行されません。実際には、この原子性は必要ありません。必要なのは条件付き実行です。

これはうまくいくはずです:

with r.pipeline() as pipe:
    while True:
        try:
            pipe.watch("a_hash")
            if pipe.exists("a_hash"):
                pipe.multi()
                pipe.hset("a_hash", "key", "value")
                pipe.execute()
            break
        except redis.WatchError:
            continue
        finally:
            pipe.reset()

EXISTS の後、MULTI の前にキーが削除された場合、ウォッチのおかげで HSET は実行されません。

Redis 2.6 では、おそらくLua サーバーサイド スクリプトの記述がより簡単になり、より効率的になります。

于 2012-06-11T22:21:25.797 に答える