Как создать распределенную блокировку с помощью Redis?
В документации redis я обнаружил, что примитивная блокировка может быть реализована через SETNX:
http://redis.io/commands/setnx
C4 отправляет SETNX lock.foo для получения блокировки
Сбитый клиент C3 все еще держит его, поэтому Redis ответит с 0 до C4.
C4 отправляет GET lock.foo, чтобы проверить, не истек ли срок блокировки. Если это не так, он будет спать некоторое время и повторить попытку с самого начала.
Вместо этого, если срок действия блокировки истек, потому что время Unix на lock.foo старше, чем текущее время Unix, C4 пытается выполнить:
GETSET lock.foo
Из-за семантики GETSET C4 может проверить, является ли старое значение, сохраненное в ключе, все еще устаревшей временной меткой. Если это так, замок был приобретен.
Если другой клиент, например C5, был быстрее, чем C4, и получил блокировку с помощью операции GETSET, операция C4 GETSET вернет отметку времени с истекшим сроком действия. С4 просто перезапустится с первого шага. Обратите внимание, что даже если в будущем C4 установит ключ на несколько секунд, это не проблема.
Однако, как прокомментировали некоторые пользователи, использование метки времени UNIX в качестве срока действия требует полной синхронизации времени клиента и сервера. Есть ли лучшая альтернатива для создания глобальной / распределенной блокировки в Redis?