Как избежать «повторных штормов» в распределенных сервисах?

10

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

Возьмите этот пример:

Образец Архитектуры

Например, если бы службы в целом были масштабированы для поддержки 80 000 запросов в секунду и работали с пропускной способностью около 80%, скачок трафика, который привел к тому, что служба получала 101 000 запросов в секунду, привел бы к сбою 1000 из этих запросов.

Когда вступают в силу политики повторных попыток, вы получаете более 1000+ запросов, в зависимости от того, где был обнаружен сбой, который увеличил бы сервис в целом до 102 000 запросов в секунду - оттуда ваша служба уходит в смертельную спираль, удваивая число неудавшихся запросов каждую секунду.

Помимо массового чрезмерного предоставления услуг за пределами прогнозируемой максимальной транзакции, что было бы неэффективно. Какие стратегии вы можете использовать, чтобы избежать «повторных штормов»?

Ричард Слейтер
источник
Если 100kQPS - это 80% емкости, то 101kQPS не должен приводить к сбоям 1 КБ, это должно приводить к нулевым сбоям - не в этом ли смысл избыточного выделения ресурсов?
Адриан,
@ Адриан, вы правы, это был надуманный пример, чтобы объяснить суть - я пытался быть достаточно редуцирующим, чтобы ясно изложить свою точку зрения, не будучи чрезмерно абстрактным. Я исправил «масштабирован для поддержки 100 000», чтобы «масштабирован для поддержки 80 000».
Ричард Слейтер

Ответы:

7

Это зависит от того, чего вы пытаетесь избежать.

Если вы пытаетесь избежать какого-либо прерывания службы чего-либо, что является действительно критичным сервисом (я думаю, что «люди умрут, если мой вызов API не будет должным образом обслужен»), вам нужно просто выделить бюджет на огромные неэффективности, которые приходят из-за чрезмерного выделения выделенных ресурсов. И да, они должны быть выделены, ни один из них не учитывает всплески трафика, так как скачки нескольких сервисов могут привести к отключению.

В гораздо более вероятном сценарии прекращения работы вашего сервиса будет неудобно, вы можете решить проблему как со стороны клиента, так и со стороны сервера. Хотя стоит отметить, что на самом деле логически невозможно решить проблему большого объема трафика, потому что без обработки трафика (который потребляет ресурсы) вы не можете знать, является ли это повторной попыткой, если это повторная попытка запроса, который был успешным, но неправильно обработан клиентом, если это DDOS и т. д. Но вы можете смягчить воздействие.

В коде клиента напишите разумную логику повторных попыток, которая имеет верхний предел и механизм для постепенного отказа. Таким образом, вы не запутываете своих пользователей в бесконечном цикле неудачных запросов и просто даете им ошибку, сообщая им попробовать все, что они только что сделали за короткое время.

Для вашей серверной инфраструктуры самое простое решение - регулирование. Жесткие ограничения на запросы, особенно если вы можете попытаться логически распределить их в зависимости от вашего конкретного случая использования (т. Е. Если у вас есть централизованная служба, вы принимаете жесткие решения, хотите ли вы начать блокировать географически удаленные запросы, которые могут привести к зависанию потоков на стороне сервера? Или вы хотите равномерно распределить неизбежное, но незначительное отключение? и т. д.) В основном все сводится к тому, что возврат 503 преднамеренно из шлюза обходится намного дешевле, чем пропуск запроса и отправка 504. тем не мение. В основном вынуждают клиентов вести себя в зависимости от того, что вы в настоящее время можете предоставить, и предоставлять правильные ответы, чтобы клиенты могли реагировать соответствующим образом.

hvindin
источник
5

Одним из способов предотвращения повторных штормов является использование механизмов отката.

Из раздела Реализация отката при повторных попытках руководства по разработке приложений для Google App Engine :

Ваш код может повторить попытку в случае сбоя, независимо от того, вызываете ли вы такую ​​службу, как Cloud Datastore, или внешнюю службу, используя URL Fetch или Socket API. В этих случаях вы всегда должны реализовывать рандомизированную политику экспоненциального отката, чтобы избежать проблемы стада громов . Вам также следует ограничить общее количество повторных попыток и обработать сбои после достижения максимального предела повторных попыток.

В большинстве API-интерфейсов GAE такие механизмы / политики отката уже включены по умолчанию.

Дэн Корнилеску
источник
Спасибо, реализация механизмов отката - отличный совет, я обычно обращаюсь к настраиваемому экспоненциальному откату, используя блок приложения Transient Fault Handling . Тем не менее, благодаря более чем 5-летнему опыту работы с гипермасштабными приложениями в Azure, даже с экспоненциальным откатом на месте, «повторные штормы» все еще случаются довольно часто - мне никогда не удавалось найти работоспособную стратегию для их предотвращения.
Ричард Слейтер