Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Контролируйте скорость, с которой приложение отправляет запросы в службу, чтобы оставаться в пределах ограничений службы по дросселированию и её общей пропускной способности. Этот подход помогает избежать или минимизировать ошибки регулирования и более точно прогнозировать пропускную способность.
Ограничение скорости подходит во многих сценариях, но особенно полезно для крупномасштабных повторяющихся автоматических задач, таких как пакетная обработка.
Контекст и проблема
При выполнении большого количества операций в службе с ограничением запросов трафик может увеличиться, а пропускная способность — снизиться, поскольку необходимо отслеживать отклонённые запросы и затем повторно выполнять эти операции. По мере увеличения числа операций ограничение пропускной способности может потребовать многократной повторной отправки данных, что приводит к более заметному снижению производительности.
Например, рассмотрим следующий неудачный процесс повторных попыток при возникновении ошибок при загрузке данных в Azure Cosmos DB:
Приложение должно принять 10 000 записей в Azure Cosmos DB. Каждая запись требует 10 единиц запроса (RU) на загрузку, поэтому для выполнения задачи в общей сложности требуется 100 000 RU.
Для экземпляра Azure Cosmos DB выделено 20 000 единиц запросов (RU) пропускной способности.
Вы отправляете все 10 000 записей в Azure Cosmos DB. 2 000 записей успешно записываются, а 8 000 записей отклоняются.
Вы отправляете оставшиеся 8000 записей в Azure Cosmos DB. 2000 записей успешно написаны, и 6000 записей отклоняются.
Вы отправляете оставшиеся 6000 записей в Azure Cosmos DB. 2000 записей успешно написаны, и 4000 записей отклоняются.
Вы отправляете оставшиеся 4000 записей в Azure Cosmos DB. 2000 записей успешно написаны, и 2000 записей отклоняются.
Вы отправляете оставшиеся 2000 записей в Azure Cosmos DB. Все записи записываются успешно.
Задание приема успешно завершается, но только после отправки 30 000 записей в Azure Cosmos DB. Весь набор данных состоит только из 10 000 записей.
Существуют другие факторы, которые следует учитывать в этом примере:
Большое количество ошибок также может привести к дополнительной работе для регистрации этих ошибок и обработки результирующих данных журнала. Предыдущий подход обрабатывает 20 000 ошибок, и ведение журнала этих ошибок может наложить затраты на обработку, память или ресурс хранилища.
Так как вы не знаете ограничения регулирования службы приема, у вас нет способа задать ожидания на время обработки данных. Ограничение скорости позволяет вычислить время, необходимое для приема.
Решение
Ограничение скорости может уменьшить трафик и потенциально повысить пропускную способность, уменьшая количество записей, отправляемых в службу в течение определенного периода времени.
Служба может ограничивать частоту запросов по различным метрикам в течение определённого периода времени, например:
- Количество операций (например, 20 запросов в секунду).
- Объем данных (например, 2 ГиБ в минуту).
- Относительная стоимость операций (например, 20 000 RUs в секунду).
Независимо от метрики, используемой для регулирования, реализация ограничения скорости будет включать управление числом и (или) размером операций, отправленных в службу в течение определенного периода времени. Ограничение частоты запросов помогает оптимизировать использование сервиса, не превышая допустимый предел троттлинга.
В сценариях, когда ваши API-интерфейсы могут обрабатывать запросы быстрее, чем позволяют ограниченные службы приема, необходимо управлять скоростью использования этой службы. Рассмотрение ограничения только как несоответствия скорости передачи данных и буферизация запросов приема до тех пор, пока служба не будет восстановлена, создают риск. Если приложение перестает отвечать на этот сценарий, все буферные данные могут быть потеряны.
Чтобы избежать этого риска, рассмотрите возможность отправки своих записей в отказоустойчивую систему обмена сообщениями, которая может обрабатывать полную скорость приема данных. (Такие службы, как Центры событий Azure могут обрабатывать миллионы операций в секунду.) Затем можно использовать один или несколько процессоров заданий для чтения записей из системы обмена сообщениями с контролируемой скоростью, которая находится в пределах ограничений управляемой службы. Отправка записей в систему обмена сообщениями позволяет экономить внутреннюю память, поскольку дает возможность извлекать из очереди только те записи, которые могут быть обработаны за данный интервал времени.
Azure предоставляет несколько устойчивых служб обмена сообщениями, которые можно использовать с этим шаблоном, в том числе:
При отправке записей используемый вами период времени может быть меньше, чем период, по которому служба применяет ограничение пропускной способности. Системы часто устанавливают ограничения для интервалов времени, которые легко понять и с которыми удобно работать. Однако для компьютера под управлением службы эти интервалы времени могут быть очень длинными по сравнению с тем, насколько быстро он может обрабатывать информацию. Например, система может вводить ограничение на количество операций в секунду или в минуту, но обычно код выполняет обработку на уровне наносекунд или миллисекунд.
Хотя это не обязательно, часто рекомендуется отправлять меньшее количество записей чаще для повышения пропускной способности. Таким образом, вместо того чтобы пытаться выпускать записи пакетами раз в секунду или раз в минуту, можно делать это более дробно, чтобы потребление ресурсов — памяти, процессора и сети — было более равномерным. Этот подход предотвращает потенциальные узкие места, вызванные внезапными всплесками запросов. Например, если служба разрешает 100 операций в секунду, реализация ограничения скорости может достигать равномерного распределения запросов, выпуская по 20 операций каждые 200 миллисекунд, как показано на следующем графике.
Кроме того, иногда нескольким нескоординированным процессам необходимо совместно использовать сервис с ограниченной пропускной способностью. Чтобы реализовать ограничение скорости в этом сценарии, можно логически секционировать емкость службы, а затем использовать распределенную систему взаимного исключения для управления монопольными блокировками этих секций. Затем нескоординированные процессы могут конкурировать за блокировки этих разделов всякий раз, когда им требуется дополнительная ёмкость. Для каждого раздела, для которого процесс удерживает блокировку, ему выделяется определенный объем ресурсов.
Например, если система с ограничением пропускной способности допускает до 500 запросов в секунду, можно создать 20 разделов по 25 запросов в секунду каждый. Если процесс требуется для выдачи 100 запросов, он может попросить распределенную систему взаимного исключения для четырех разделов. Система может выделить два раздела на 10 секунд. Затем процесс будет ограничивать скорость до 50 запросов в секунду, завершить задачу в два секунды, а затем освободить блокировку.
Одним из способов реализации этого шаблона является использование служба хранилища Azure. В этом сценарии вы создаете один BLOB-объект размером 0 байт для каждого логического раздела в контейнере. Затем ваши приложения могут получать эксклюзивные блокировки непосредственно для этих BLOB-объектов на короткий период времени (например, на 15 секунд). Для каждой аренды, по которой одобрена заявка, можно использовать объём ёмкости этого раздела. Затем приложение должно отслеживать срок аренды, чтобы, когда этот срок истечёт, оно могло прекратить использование предоставленной ему мощности. При реализации этого шаблона часто требуется, чтобы каждый процесс пытался арендовать случайную секцию, когда она нуждается в емкости.
Чтобы уменьшить задержку, можно выделить небольшое количество монопольной емкости для каждого процесса. Затем процесс будет запрашивать аренду общей мощности только в том случае, если ему потребуется превысить свою зарезервированную мощность.
В качестве альтернативы служба хранилища Azure вы также можете реализовать эту систему управления арендой с помощью таких технологий, как ZooKeeper, etcd и Redis/Redsync.
Проблемы и рекомендации
При принятии решения о том, как реализовать этот шаблон, учитывайте следующие моменты:
Хотя шаблон ограничения скорости может уменьшить количество ошибок регулирования, приложение по-прежнему должно правильно обрабатывать любые ошибки регулирования, которые могут возникнуть.
Убедитесь, что повторные попытки согласованы с ограничением скорости. Бездумные или чрезмерно агрессивные повторные попытки могут увеличить нагрузку и вызвать штормы повторных запросов, поэтому передавайте сигналы обратного давления (например, HTTP 429 с
Retry-After) и используйте ограниченное число повторных попыток с небольшими случайными задержками между попытками.Если в вашем приложении есть несколько направлений работы, которые обращаются к одному и тому же сервису с ограничением частоты запросов, необходимо учесть их все в стратегии ограничения частоты запросов. Например, вы можете поддерживать массовую загрузку записей в базу данных, а также запрашивать записи в той же базе данных. Вы можете управлять пропускной способностью, обеспечив, чтобы все потоки работ проходили через один и тот же механизм ограничения частоты запросов. Кроме того, можно зарезервировать отдельные пулы емкости для каждого рабочего потока.
Ограниченная служба может использоваться в нескольких приложениях. В некоторых случаях можно координировать это использование (как показано ранее в этой статье). Если вы начинаете видеть больше ошибок ограничения запросов, чем ожидалось, это может указывать на конкуренцию между приложениями при доступе к службе. В этом случае может потребоваться временно сократить пропускную способность, введенную механизмом ограничения скорости, пока использование других приложений не уменьшится.
Когда следует использовать этот шаблон
Используйте этот шаблон, когда:
Необходимо уменьшить количество ошибок из-за ограничения частоты запросов, возникающих при обращении к сервису с ограничением частоты запросов.
Вы хотите свести сетевой трафик к минимуму по сравнению с наивными стратегиями повторных попыток при ошибке.
Необходимо сократить потребление памяти, извлекая записи из очереди только при наличии достаточных ресурсов для их обработки.
Этот шаблон может быть не подходит, если:
Операция требует немедленного, синхронного завершения с очень низкой задержкой и не может терпеть очередь или отложенную обработку.
Основное узкое место не является скоростью запросов, но вместо этого является параллелизмом или конфликтом ресурсов (например, насыщенность ЦП или длительные работы в полете). В этих случаях более подходящими являются элементы управления масштабированием или параллелизмом.
Проектирование рабочей нагрузки
Оцените, как использовать шаблон ограничения скорости в проектировании рабочей нагрузки для решения целей и принципов, описанных в основных принципах Azure Well-Architected Framework. В следующей таблице приведены рекомендации по использованию этого шаблона для целей каждого компонента.
| Столп | Как этот шаблон поддерживает цели основных компонентов |
|---|---|
| Решения по проектированию надежности помогают рабочей нагрузке стать устойчивой к сбоям и гарантировать, что она восстанавливается до полнофункционального состояния после сбоя. | Эта тактика защищает клиента, признавая и учитывая ограничения и затраты на взаимодействие со службой, когда служба предпочитает избежать чрезмерного использования. - RE:07 Самосохранение |
Если этот шаблон вводит компромиссы внутри столпа, рассмотрите их против целей других столпов.
Example
В следующем примере приложения пользователи могут отправлять записи различных типов в API. Каждый тип записи имеет уникальный обработчик заданий, выполняющий следующие действия:
- Проверка
- Обогащение
- Вставка записи в базу данных
Все компоненты приложения (API, обработчик заданий А и обработчик заданий B) — это отдельные процессы, которые можно масштабировать независимо. Процессы не взаимодействуют друг с другом напрямую.
В этом примере каждая аренда BLOB-объекта представляет фиксированную долю допустимой пропускной способности базы данных. Процессор может извлекать из очереди и записывать данные только со скоростью, равной суммарной скорости аренд, которыми он в данный момент владеет. По мере того как процессоры со временем получают или теряют аренды, их допустимая скорость записи меняется, что позволяет удерживать общий трафик базы данных в пределах заданного лимита, при этом не останавливая выполнение всех задач в очереди.
Эта схема включает следующий рабочий процесс:
- Пользователь отправляет 10 000 записей типа A в API.
- API ставит эти 10 000 записей в очередь A.
- Пользователь отправляет 5000 записей типа B в API.
- API ставит эти 5 000 записей в очередь B.
- Обработчик заданий A видит, что очередь A содержит записи, и пытается получить исключительную аренду BLOB-объекта 2.
- Обработчик заданий B видит, что очередь B содержит записи и пытается получить монопольную аренду на BLOB-объект 2.
- Обработчик заданий A не может получить аренду.
- Обработчик заданий B получает аренду для BLOB-объекта 2 на 15 секунд. Теперь он может ограничить скорость запросов к базе данных со скоростью 100 в секунду.
- Обработчик заданий B извлекает 100 записей из очереди B и записывает их.
- Проходит одна секунда.
- Обработчик заданий A видит, что в очереди A больше записей, и пытается получить исключительную аренду на BLOB-объект 6.
- Обработчик заданий B видит, что очередь B имеет больше записей и пытается получить монопольную аренду на BLOB-объект 3.
- Обработчик заданий A получает аренду для BLOB-объекта 6 на 15 секунд. Теперь он может ограничить скорость запросов к базе данных со скоростью 100 в секунду.
- Обработчик заданий B получает аренду для BLOB-объекта 3 сроком на 15 секунд. Теперь он может ограничить скорость запросов к базе данных со скоростью 200 в секунду. (У неё также есть право аренды на blob 2.)
- Обработчик заданий A извлекает 100 записей из очереди A и записывает их.
- Обработчик заданий B извлекает 200 записей из очереди B и записывает их.
- Проходит одна секунда.
- Обработчик заданий A видит, что очередь A содержит больше записей, и пытается получить исключительную аренду на BLOB-объект 0.
- Обработчик заданий B видит, что в очереди B больше записей, и пытается получить эксклюзивную аренду на объект blob 1.
- Обработчик заданий A получает право аренды для BLOB-объекта 0 на 15 секунд. Теперь он может ограничить скорость запросов к базе данных со скоростью 200 в секунду. (Она также имеет договор аренды на blob 6.)
- Обработчик заданий B получает право аренды на объект BLOB 1 на 15 секунд. Теперь он может ограничить скорость запросов к базе данных со скоростью 300 в секунду. (Она также владеет правами аренды на блоки 2 и 3.)
- Обработчик заданий A извлекает 200 записей из очереди A и записывает их.
- Обработчик заданий B извлекает 300 записей из очереди B и записывает их.
- И так далее.
Через 15 секунд одно или оба задания по-прежнему не будут завершены. По мере истечения сроков аренды обработчик также должен уменьшить количество запросов, которые он извлекает из очереди и записывает.
Реализации этого шаблона доступны на разных языках программирования:
- Реализация Go доступна на сайте GitHub.
- Реализация Java доступна на сайте GitHub.
Дальнейшие действия
При реализации этого шаблона также может быть актуально следующее руководство.
Расширенное регулирование запросов с помощью Azure API Management. Используйте это как дополнительный контроль допуска на периферии, чтобы обеспечить ограничения на частоту вызовов и квоты для каждого ключа, а также возвращать клиентам согласованные сигналы перегрузки.
Выбор службы обмена сообщениями Azure. Выберите лучшую надежную платформу обмена сообщениями для буферизации и контролируемой загрузки данных.
Обработка временных сбоев в приложениях Azure. Создайте поведение повторных попыток, чтобы клиенты отключлись правильно при достижении ограничений.
Связанные ресурсы
При реализации этого шаблона также могут быть важны следующие шаблоны и рекомендации.
Throttling. Шаблон ограничения частоты запросов обычно применяется в ответ на ограничение запросов со стороны сервиса.
Retry. Когда запросы к службе с ограничением запросов приводят к ошибкам из-за ограничения запросов, обычно целесообразно повторить такие запросы через подходящий интервал.
Выравнивание нагрузки на основе очереди аналогично паттерну ограничения скорости, но отличается в нескольких ключевых аспектах:
Ограничение скорости не обязательно требует использования очередей для управления нагрузкой, но требуется использовать надежную службу обмена сообщениями. Например, шаблон ограничения скорости может использовать такие службы, как Apache Kafka или Центры событий.
Шаблон ограничения скорости вводит концепцию распределенной системы взаимного исключения в разделах, которая позволяет управлять пропускной способностью для нескольких нескоординированных процессов, взаимодействующих с одним и тем же сервисом с ограничением запросов.
Шаблон выравнивания нагрузки на основе очереди применим в тех случаях, когда между службами наблюдается несоответствие в производительности или требуется повысить отказоустойчивость. Таким образом, это более широкий паттерн, чем ограничение частоты запросов, которое главным образом связано с эффективным доступом к сервису с ограничением скорости обработки запросов.