Кейс: распределённый лок через Redis потерян из-за GC pause

SETNX с TTL — стандартная схема распределённого лока: клиент ставит ключ с истечением, работает, снимает лок вручную. Проблема начинается, когда TTL меньше возможной паузы GC на клиенте.

Если Stop-The-World пауза — например, полный GC на большом heap — превышает TTL лока, Redis успевает удалить ключ по истечении. Второй клиент забирает лок и начинает работать, пока первый ещё не вышел из паузы и уверен, что лок у него.

Результат — два инстанса одновременно считают себя владельцами ресурса. Это не баг Redis и не баг кода блокировки, а гонка между TTL и паузой JVM, которую тесты на локальной машине не воспроизводят.

Что спросят следом: как защититься — fencing token, монотонно растущий номер версии, который проверяет получатель ресурса перед каждой операцией, а не только при захвате лока.

TTL лока — это ставка на то, что клиент успеет всё сделать за это время, включая случайную паузу GC, которую вы не контролируете.

Тренажёр: 600 вопросов, мок с таймером, план повторов

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки