Распределённые системы
Retry amplification: тест с выбором ответа
Шесть вопросов поперёк всего юнита. Каждый отражает решение, которое ты принимаешь посреди инцидента — не определение для заучивания, а число fan-out, которое надо посчитать, и фикс, который надо проранжировать, пока бэкенд горит.
Убедись, что связываешь математику retry-fan-out, metastable-петлю и лестницу защит — jitter, retry budget, circuit breaker, идемпотентность, проброс дедлайна — тот синтез, к которому вёл весь юнит.
Запрос проходит через 5 слоёв сервисов, и каждый слой делает 3 ретрая при сбое. Сколько в худшем случае вызовов придёт к самой глубокой зависимости на один сбойный запрос и почему это застаёт врасплох?
8-секундный failover базы, запустивший инцидент, завершился 30 минут назад, но флот всё ещё лежит под retry storm. Что на самом деле держит его внизу?
Команда добавляет ретраи с фиксированным интервалом (жди 200 мс, ретрай, жди 200 мс, ретрай) на каждом слое, чтобы «быть помягче». В следующий blip зависимости простой оказывается хуже прежнего. Почему?
Ты уже выкатил exponential backoff с full jitter на каждом слое, но полный outage зависимости всё равно гонит бэкенд к ~80x нормальной нагрузки. Чего jitter не купил и что ты добавляешь?
Circuit breaker открывается, когда частота сбоев к зависимости пересекает порог. Что это даёт такого, чего не даёт один retry budget?
Просматривая retry-конфиг сервиса, ты находишь, что он ретраит любой сбой до 3 раз — включая 400, 409-конфликты и неидемпотентные POST — без проброса дедлайна. Какие два правила он нарушает и почему они важнее всего под нагрузкой?
Сквозная линия — одно дерево решений: ретраи складываются умножением (retries^depth, поэтому 3⁵ = 243), и крошечная доля ошибок превращается в самонанесённый DDoS; затем storm самоподдерживается как metastable failure ещё долго после устранения триггера. Защиты ложатся от самой широкой к самой тонкой — jitter расцепляет толпу во времени, retry budget ~10% ограничивает объём, circuit breaker даёт окно нулевого трафика ретраев — а неоспоримые правила: ретраить только идемпотентные операции и retryable-ошибки и пробрасывать дедлайн, чтобы ни один слой не ретраил уже мёртвый запрос.