Балансировка нагрузки

Рано или поздно наступает момент, когда приложение начинает не справляться с нагрузкой и мы решаем горизонтально масштабировать нашу систему. Тогда возникает вопрос: как распределить запросы между несколькими машинами?

Для решения этой проблемы используют балансировщики нагрузки. С помощью набора алгоритмов они позволяют равномерно распределить нагрузку на сервера. Зачастую представлены в виде софтверного решения, реже как отдельные устройства.

Помимо распределения нагрузки, балансировщики также выполняют дополнительные задачи, такие как обнаружение служб и проверка работоспособности. Иногда они работают в качестве API Gateway для маршрутизации трафика или его троттлинга. Например, отправлять запросы по специфичному URL на какой-то конкретный сервис и не давать пользователям делать больше указанного порога запросов в секунду.

Обнаружение служб

Это процесс, который позволяет определить набор сервером, на которые можно отправлять запросы. Для реализации этого подхода можно использовать несколько способов:

  • Файлы конфигурации.
  • DNS
  • Zookeper, Consul и т. д.

Проверка работоспособности

Проверки работоспособности позволяют понять, какие сервера сейчас работают и могут обрабатывать запросы. Сами проверки деляться на два типа: активные и пассивные.

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

В активном режиме балансировщик периодически делает запросы на специальный эндпоинт, который проверяет состояние приложения. Их также можно разделить на несколько типов: liveness и readiness

Алгоритмы балансировки нагрузки

Все современные балансировщики имеют поддержку множества алгоритмов, которые позволяют оптимально распределить запросы. Самих алгоритмов есть огромное множество, но основных всего несколько:

  • DNS
  • Sticky Session
  • Round Robin
  • Weighted Round Robin
  • Least Connection
  • IP Hash

DNS
Самый простой способ распределить запросы это использовать DNS, он позволяет работать клиентам с несколькими серверами и повысить их доступность.  Для этого достаточно зарегистрировать несколько серверов на одно доменное имя. Когда клиент запрашивает IP адрес, DNS возвращает список адресов серверов, который каждый раз начинается с другого адреса. Такой подход похож на работу алгоритма Round Robin.

Проблема заключается в том, что DNS запросы обычно кэшируются в браузере пользователя или на уровне операционной системы. Из-за такого поведения пользователь может обращяться к неработающему серверу. Даже если оперативно удалить адрес упавшего сервера из списка, может пройти время пока DNS записи реплицируются на другие сервера и пока кэш пользователя инвалидируется.

Round Robin
Самый простой алгоритм. Балансировщик держит обычную очередь из серверов. Первый сервер в очереди обрабатывает запрос и помещается в конец очереди и так по кругу. Таким образом сервера равномерно нагружены.

Алгоритм отлично походит когда сервера в пуле имеют одинаковую мощность и время обработки запросов.

Weighted Round Robin
Тот же round robin, но имеет дополнительное свойство — вес сервера. С его помощью мы можем указать балансировщику сколько трафика отправлять на тот или иной сервер. Так сервера помощнее будут иметь больший вес и соответственно обрабатывать больше запросов чем другие сервера.

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

Алгоритм можно улучшить и учитывать не только количество соединений, но и среднее время. Тогда первым в списке будет сервер с наименьшим количеством подключений и наименьшим временем ответа. Такой алгоритм называется Least Response Time. Такой способ позволяет выровнять нагрузку если сервера отвечают с разной скоростью.

Hash
Такой способ использует в своей основе механизм хеширования. Он позволяет распределить запросы на основе хеша, для которого обычно используется IP адрес или URL. В таком случае запросы от одного и того же IP будут отправлены на один и тот же сервер. Тоже самое касается URL. Такой алгоритм обычно используют, когда сервер хранит какие-то локальные данные, которые нужны для ответа.

Примеры софтверных балансировщиков

  • HAProxy
  • nginx
  • AWS Route 53
  • AWS Elastic Load Balancer

Дополнительная информация

  • The power of two random choices. Автор предлагает отказаться от централизованной балансировки нагрузки и использовать балансировку на стороне клиента. Для этого информации и загруженности серверов сохраняется в каком-то кэше, который время от времени обновляется. Сами же клиенты будут случайным образом выбирать два сервера и отправлять запрос на менее загруженных из двух. Такой подход позволяет оптимально распределять нагрузку и избавиться от центрального балансировщика.
  • Introduction to modern network load balancing and proxying. Хорошая статья в которой описаны способы использования балансировщиков нагрузки и в чем разница между L4 и L7 балансировкой. Перевод на русский.
Поделиться
Отправить
Запинить
 133   2 мес   system-design
Популярное