Когда клиент получает ключ (A), сервер отвечает одним из трёх способов.
| Состояние ключа | Действие сервера | Ответ |
|---|---|---|
| Не зарегистрирован | Немедленная регистрация (истечение = now + lease), выдача токена | A + token + key |
| Зарегистрирован + срок истёк | Обновление (now + lease), выдача нового токена | A + token + key |
| Зарегистрирован + действителен (занят) | Постановка в очередь, ответ откладывается | При освобождении/истечении — A, при превышении wait — T |
R) ключ, он передаётся напрямую первому в очереди — без повторной конкуренции, сразу с новым токеном.lease — это страховочная сеть. Если клиент упал или забыл освободить ключ, по истечении времени lease сервер автоматически заберёт ключ обратно и сможет передать его следующему ожидающему. Поэтому, независимо от штатного потока освобождения, lease стоит устанавливать с запасом, но так, чтобы в случае гибели клиента ключ не был занят слишком долго.wait — верхняя граница ожидания получения. При значении 0 ожидание бесконечно, в остальных случаях, если за это время (в секундах) получить ключ не удалось, сервер сдаётся и отвечает T (таймаут) — без выдачи гранта, поэтому утечки блокировки не происходит.token, содержащийся в ответе A — это монотонно возрастающий u64 этого гранта. При каждом получении блокировки выдаётся значение больше любого предыдущего токена. Даже при failover новый активный узел продолжает отсчёт от значения больше максимального реплицированного токена (наследование) — поэтому токен непрерывно растёт в масштабе всего кластера.
Если защищаемый ресурс (счёт, файл, заказ и т.п.) проверяет только одно условие — "больше ли текущий токен последнего увиденного" — можно отклонить доступ клиента, который проснулся с опозданием после истечения lease и пытается использовать уже недействительный, более старый токен. Благодаря этому безопасность сохраняется, даже если сервер блокировок не абсолютно консистентен в каждый момент времени.
Официальные клиенты в целом ведут себя одинаково (подробности API для конкретного языка — в разделе Библиотеки).
lease, но так следующий ожидающий получит её быстрее).peers определяет приоритет повышения (первый в списке — наивысший приоритет). Среди живых узлов узел с наивысшим приоритетом становится активным, остальные — резервными (standby), получающими его состояние репликацией в реальном времени.M) на адрес активного и переходит туда.Ctrl+C) активный узел сначала передаёт повышение преемнику (handoff), а затем перенаправляет клиентов — так простой активного узла сводится к минимуму.Этот механизм повышения не основан на кворуме (голосовании большинством). Поэтому чётность или нечётность числа узлов значения не имеет, и сервис остаётся работоспособным, пока жив хотя бы один узел.
| Число серверов | Бесперебойность | Допустимое число одновременных сбоев | Примечание |
|---|---|---|---|
| 1 | ✗ | — | Самый быстрый вариант. При перезапуске возникает кратковременный простой |
| 2 | ✓ | 1 | Минимальная конфигурация для бесперебойности. Обычно этого достаточно |
| 3 | ✓ | 2 | Резервирование сохраняется даже при обслуживании одного узла |
| 4+ | ✓ | N−1 | Растут только затраты на распространение — не рекомендуется |
Повышение на основе приоритета не является консенсусом, поэтому в момент сетевого разделения обе стороны могут ненадолго одновременно оказаться активными, а из-за особенностей асинхронной репликации в момент failover часть грантов может быть потеряна. То есть в периоды failover/partition взаимное исключение не гарантируется на 100%. Если нужны строгие гарантии, реализуйте проверку описанного выше fencing-токена на стороне защищаемого ресурса — отклонение устаревших (меньших) токенов обеспечивает безопасность, даже если сервер блокировок не абсолютно консистентен.