Может ли ZooKeeper получить данные znode и версию данных (stat) znode за одну операцию?

Я разрабатываю приложение, которое использует ZooKeeper в качестве хранилища данных. Для одного из методов в приложении мне нужно использовать оптимистический параллельный контроль. Например, мне нужно реализовать метод get, который получает данные znode, и я использую версию данных znode для проверки оптимистичного параллельного управления. Насколько я понимаю, нельзя получить данные znode и версию данных znode за одну операцию. Если существует высокая конкуренция за обновление данных znode, метод get не будет работать, поскольку данные znode могут измениться после получения данных znode. поэтому я спрашиваю - есть ли способ получить znode data и версию znode data (или znode stat) за одну операцию без какой-либо попытки блокировки между ними?

2 ответа

В Java вы можете легко достичь желаемого:

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

Это действительно читает данные и информацию о версии (в stat объект) в одной операции. Когда вы записываете данные обратно, вы передаете номер версии, который вы получили при чтении:

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

Если есть несоответствие версии, метод сгенерирует KeeperException.BadVersionException, который дает вам оптимистическую блокировку.

В Python, использующем Kazoo, также тривиально получить статистику и реализовать некоторую оптическую блокировку. Вот эскиз:

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

Кроме того, используйте готовые рецепты, когда это возможно, так как они уже широко отлажены и должны относиться ко всем угловым случаям.

Другие вопросы по тегам