Может ли 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
Кроме того, используйте готовые рецепты, когда это возможно, так как они уже широко отлажены и должны относиться ко всем угловым случаям.