【问题标题】:can ZooKeeper get znode data and znode data version (stat) in one single operation?ZooKeeper 可以在一次操作中获取 znode 数据和 znode 数据版本(stat)吗?
【发布时间】:2013-08-01 16:48:18
【问题描述】:

我正在开发一个使用 ZooKeeper 作为数据存储的应用程序。对于应用程序中的一种方法,我需要使用乐观并发控制。例如,我需要实现一个获取 znode 数据的 get 方法,并且我使用 znode 数据版本进行乐观并发控制检查。据我了解,一次操作无法获取 znode 数据和 znode 数据版本。如果更新 znode 数据的竞争激烈,get 方法将不起作用,因为在获取 znode 数据后 znode 数据可能会发生变化。所以我在问 - 有没有一种方法可以在一次操作中获得 znode 数据和 znode 数据版本(或 znode stat),而不会在两者之间进行任何锁定尝试?

【问题讨论】:

    标签: apache-zookeeper optimistic-locking optimistic-concurrency optimistic


    【解决方案1】:

    在Java中,你可以轻松实现你想要的:

    Stat stat = new Stat();
    byte[] data = zk.getData("/path", null, stat));
    

    这确实在单个操作中读取数据和版本信息(在stat 对象中)。当你写回数据时,你传递的是你读取它时得到的版本号:

    zk.setData("/path", data, stat.getVersion());
    

    如果版本不匹配,该方法将抛出KeeperException.BadVersionException,这会给你一个乐观锁。

    【讨论】:

    • 我正在使用 Curator 2.8.0,它已被重构为 Stat stat = new Stat(); c.getData().storingStatIn(stat).forPath("/path");
    【解决方案2】:

    在使用 Kazoo 的 Python 中,获取两个统计信息并实现一些光学锁定也很简单。这是一个草图:

    while True:
        data, stat = zk.get("/path")
        # do something with the data and then:
        try:
            zk.set("/path", new_data, stat.version)
            break
        except BadVersionError:
            continue  # or pass
    

    此外,请尽可能使用预制配方,因为它们已经经过广泛调试,并且应该处理所有极端情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-11
      • 1970-01-01
      • 2015-10-29
      • 1970-01-01
      • 2019-03-12
      相关资源
      最近更新 更多