Основные данныеКоординация

Распределённые блокировки

Следите, чтобы задачу одновременно выполнял только один воркер, с блокировками, которые истекают сами и безопасно снимаются владельцем.

команда для получения
1
команда для безопасного снятия
1
скриптов Lua
0
Шаг 1 из 5
Воркер A берёт блокировку

NX берёт её, только если никто не держит. PX 30000 делает так, что она истекает через 30 секунд, если A умирает.

Пример сеансаplaying
# Воркер A берёт блокировку
hotkv> SET lock:billing-run tok-a81f NX PX 30000
OK

Анимированная демонстрация с настоящими командами HotKV и примерами ответов. Нажмите на любой шаг, чтобы перейти к нему. Команды и ответы остаются на английском, ровно так, как вы вводите и видите их в HotKV.

Проблема

Задания cron на нескольких машинах, списания платежей и пересборка кеша не должны выполняться одновременно дважды. Блокировка без срока жизни держится вечно, если её владелец упал, а снятие блокировки простым DEL может удалить чужую блокировку после того, как ваша истекла.

Как с этим справляется HotKV

SET с NX и PX получает блокировку, только если её никто не держит, и задаёт ей срок жизни, чтобы упавший владелец не мог держать её вечно. Каждый владелец хранит в качестве значения случайный токен. DELEX с IFEQ удаляет блокировку, только если в ней по-прежнему ваш токен, - это безопасное снятие, для которого раньше нужен был скрипт Lua.

Шаг за шагом

Что происходит, команда за командой

  1. 01

    Воркер A берёт блокировку

    NX берёт её, только если никто не держит. PX 30000 делает так, что она истекает через 30 секунд, если A умирает.

    SET lock:billing-run tok-a81f NX PX 30000
  2. 02

    Воркеру B отказывают

    Блокировка удерживается, поэтому B получает nil и пропускает этот запуск.

    SET lock:billing-run tok-b22c NX PX 30000
  3. 03

    A выполняет работу

    Задачу расчёта по счетам выполняет только один воркер.

    PTTL lock:billing-run
  4. 04

    Снимаем только свою блокировку

    DELEX удаляет ключ, только если значение по-прежнему токен A.

    DELEX lock:billing-run IFEQ tok-a81f
  5. 05

    Неверный токен ничего не делает

    Если бы A оказался слишком медленным и блокировку теперь держал B, снятие со стороны A оставило бы блокировку B нетронутой.

    DELEX lock:billing-run IFEQ tok-stale
Где это уместно

Реальные сценарии

Плановые задания

Один и тот же cron запускается на каждом экземпляре, а блокировка гарантирует, что работу выполняет ровно один из них.

Платежи

Операции списания и возврата по одному заказу сериализуются и никогда не пересекаются.

Защита от лавины в кеше

Дорогую запись кеша пересобирает только один запрос, а остальные ждут или отдают устаревшее значение.

Встроено

Что вы получаете

Получение со сроком жизни

SET NX PX берёт блокировку, только если она свободна, с тайм-аутом.

SETNXPX

Безопасное снятие

DELEX IFEQ удаляет только если значение совпадает с вашим токеном.

DELEX

Продление во время работы

Проверьте оставшееся время и продлите его для долгих заданий.

PTTLPEXPIRE

Сравнение по дайджесту

Для больших значений DELEX IFDEQ сравнивает дайджест вместо полного значения.

DIGESTIFDEQ
Справочник:SETDELEXDIGEST

Частые вопросы

Почему просто не сделать DEL для блокировки?

Если ваша блокировка истекла и её взял другой воркер, простой DEL удалил бы его блокировку. DELEX IFEQ удаляет её, только пока в ней ваш токен.

Каким должен быть срок жизни?

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

Нужен ли Lua для безопасного снятия?

Нет. DELEX выполняет сравнение и удаление одной командой.

Связанные сценарии

Попробуйте на своей нагрузке

HotKV понимает протокол Redis, поэтому вы можете подключить к нему существующий клиент и выполнить те же команды.