Кейс: распределённый лок через Redis потерян из-за GC pause
SETNX с TTL — стандартная схема распределённого лока: клиент ставит ключ с истечением, работает, снимает лок вручную. Проблема начинается, когда TTL меньше возможной паузы GC на клиенте.
Если Stop-The-World пауза — например, полный GC на большом heap — превышает TTL лока, Redis успевает удалить ключ по истечении. Второй клиент забирает лок и начинает работать, пока первый ещё не вышел из паузы и уверен, что лок у него.
Результат — два инстанса одновременно считают себя владельцами ресурса. Это не баг Redis и не баг кода блокировки, а гонка между TTL и паузой JVM, которую тесты на локальной машине не воспроизводят.
Что спросят следом: как защититься — fencing token, монотонно растущий номер версии, который проверяет получатель ресурса перед каждой операцией, а не только при захвате лока.
TTL лока — это ставка на то, что клиент успеет всё сделать за это время, включая случайную паузу GC, которую вы не контролируете.
Тренажёр: 600 вопросов, мок с таймером, план повторов
senior·base — что спрашивают на самом деле
В этом посте были ссылки, но мы их удалили по правилам Сетки