Озабоченность по поводу рецепта замка
При чтении ZooKeeper рецепта блокировки я смутился. Похоже, что этот рецепт для распределенных шлюзов не может гарантировать "любой моментальный снимок, когда два клиента не считают, что они имеют один и тот же замок" . Но так как ZooKeeper настолько широко принят, если в справочной документации были ошибки, кто-то должен был это указать давно, так что я понял неправильно?
Цитата рецепт для распределенных блокировок:
Блокировка
Полностью распределенные блокировки, которые глобально синхронны, значение при любом моментальном снимке, когда два клиента не считают, что они имеют ту же блокировку. Они могут быть реализованы с помощью ZooKeeeper. Как и в случае очередей приоритетов, сначала определите блокировку node.
- Вызовите create() с именем пути "locknode/guid-lock-" и установите последовательность и эфемерные флаги.
- Вызовите getChildren() на блокировке node без установки флага часов (это важно, чтобы избежать эффекта стада).
- Если путь, созданный на шаге 1, имеет суффикс с наименьшим порядковым номером, клиент имеет блокировку, и клиент выходит из протокола.
- Клиент вызывает exists() с флагом часов, установленным на пути в каталоге блокировки со следующим нижним порядковым номером.
- if exists() возвращает false, перейдите к шагу 2. В противном случае дождитесь уведомления для имени пути с предыдущего шага, прежде чем перейти к шагу 2.
Рассмотрим следующий случай:
Является ли это допустимым сценарием?
Ответы
Ответ 1
Сценарий, который вы описали, может возникнуть. Клиент 1 считает, что у него есть блокировка, но на самом деле его сеанс завершен, и клиент 2 получает блокировку.
Клиентская библиотека ZooKeeper сообщит клиенту 1, что его соединение отключено (но клиент не знает, что срок действия сеанса истек, пока клиент не подключится к серверу), поэтому клиент может написать код и предположить, что его блокировка был потерян, если он был слишком долго отключен. Но поток, который использует блокировку, должен периодически проверять, что блокировка по-прежнему действительна, что по своей природе является безупречным.
Ответ 2
... Но, Zookeeper может подумать, что сеанс client1 отключен, а затем...
Из документации Zookeeper:
- Удаление node приведет к тому, что один клиент проснется с тех пор каждый node просматривается ровно одним клиентом. Таким образом, вы избегаете стадо.
- Нет опроса или тайм-аутов.
Итак, я не думаю, что проблема, которую вы описываете, возникает. Мне кажется, что существует риск зависания блокировок, если что-то происходит с клиентами, которые их создают, но сценарий, который вы описываете, не должен возникать.