Sep 7, 2020 · 3 min read
В опросах в твитере и телеграме уверенно побеждают балансеры. В этой статье сделаем небольшой обзор на балансеры, как одну из важных частей в распределённых системах: какую проблему решают, как реализованы.
Why? #
Когда комьютер (читай приложение) существует в единственном экземпляре всё просто. Каждый запрос будет обработан именно этим самым инстансом.
Рано или поздно одного приложения станет не хватать: кончатся соединения, канал забьётся и т.д. Решается это проблема поднятием второго, третьего, десятого инстанса приложения, на других машинах.
Во-первых, появляется задача маршрутизации запросов между различными инстансами приложения, т.к. наше доменное имя скорее всего резолвится в единственный IP-адрес.
Это, кстати, не обязательно так. Можно распределять запросы по различным серверам на уровне DNS. Пример как это работает в Amazon Route 53.
Во-вторых, балансеры не просто распределяют запросы, они балансируют нагрузку.
Нагрузка это что? Это хороший вопрос. В зависимости от конкретного профиля нагрузки есть разные алгоритмы. Рассмотрим некоторые из них.
Strategies #
Во-первых, стоит убедиться, что сервер вообще жив, прежде чем давать на него нагрузку. Для этого, обычно, делают специальный endpoint healthcheck
, который просто отвечает 200 и ничего не делает.
Балансер держит пул доступных серверов, периодически опрашивает healthcheck
и убирает из пула нерабочий сервер. Точнее переносит в другой пул, чтобы проверить потом и вернуть снова в рабочий, если сервер ожил.
Итак, какие же есть стратегии.
Least Connection Method #
Балансер держит очередь с приоритетом, сортируя сервера по количеству активных соединений. Первым в очереди держим сервер с минимальным количеством соединений.
Когда выгодно? Когда много активных соединений. Скажем делаем стриминг или чат.
Least Response Time Method #
Улучаем предыдущий способ. Кроме количества активных соединений так же учитываем среднее время ответа. Зачем? Соединения неравнозначны, т.е. в зависимости от того, что там на серверах обрабатывается загружены они по-разному.
Round Robin Method #
Самый простой алгоритм. Балансер держит обычную очередь, берёт первый доступный сервер из пула, роутит трафик туда, кладёт этот сервер в конец очереди. Таким образом сервера равномерно нагружены.
Подходит когда нет активных соединений и среднее время ответа распределено нормально, по Гауссу, т.е. все сервера более или менее равнозначны по смыслу.
IP Hash #
Используем некоторый алгоритм шардирования по IP-адресам (клиента и сервера), который имеет смысл в нашем конкретном случае. Может быть удобно, например, если после реконнекта важно попасть на ту же самую машинку.
How? #
Я несколько раз упомянул «очередь», так что кажется, что балансер — исключительно софт. Я и сам так думал, однако есть и хардверные решения, например, Citrix NetScaler. Если хочется получить максимальную производительность и денег вагон.
В реальности, конечно, используется и то и то. Скажем, хардверные балансеры роутят вообще весь трафик во внутреннюю сеть, а дальше уже работают выделенные сервера с софтом. Их можно ставить между любыми компонентами системы: инстансами приложения, кешами а-ля Redis, инстансами базы и т.д., при необходимости.
Конкретный пример софтверного решения — HAProxy.
Резервируем порты под различные пулы, например, 9000
это приложение, 9001
база на запись, 9002
база на чтение. Настраиваем HAProxy так, что весь трафик с определённых портов идёт в соответствующие пулы инстансов. Для каждого пула можно выбрать свою стратегию.
Redundancy #
Разве балансер не будет критическим узлом системы, раз он роутит весь трафик? Так и есть. Поэтому и сам балансер представляет собой пул серверов: отказывает один, на помощь приходит другой.
Вообще, это нормальная история в распределённых системах — на всякий случай надо иметь всего как минимум по два 😃
Материалы #
- https://avinetworks.com/what-is-load-balancing/
- https://lethain.com/introduction-to-architecting-systems-for-scale/
- https://en.wikipedia.org/wiki/Load_balancing_(computing)
PS. Обсудить можно в телеграм-чате любознательных программистов. Welcome! 🤗
Подписывайтесь на мой твитер или канал в телеграме, чтобы узнавать о новых разборах задач.