Систем дизайн: алгоритмы балансировки нагрузки
Глубокий разбор алгоритмов балансировки нагрузки — от простого Round Robin до сложных методов на основе Least Connections и Hash-Based. Статья обязательна к прочтению для всех, кто готовится к собеседованиям по системному дизайну и проектирует распределенные системы.
1К открытий4К показов
Мы подготовили перевод статьи автора Сома с портала Dev.to с комментариями экспертов.
Если вы готовитесь к собеседованиям по системному проектированию, обязательно уделите внимание изучению алгоритмов балансировки нагрузки. Наряду с API Gateway, кэшированием, ограничением скорости запросов и распределёнными очередями сообщений, это одна из ключевых основ системного проектирования, которую стоит освоить в совершенстве.
В современном мире облачных вычислений, распределённых систем и сетевых архитектур балансировка нагрузки играет критически важную роль, обеспечивая оптимальную производительность, надёжность и масштабируемость сервисов.
Это также одно из обязательных условий горизонтального масштабирования: чтобы реализовать его, нужен балансировщик нагрузки, распределяющий трафик между несколькими узлами или серверами.
Хотя многие разработчики в целом представляют, что такое балансировка нагрузки, далеко не все понимают, как именно она работает и что собой представляет алгоритм балансировки нагрузки. Например, не каждый знает про простой алгоритм циклического перебора (round robin), при котором одно сообщение отправляется на один сервер, а следующее — на другой. Между тем существуют и более сложные методы балансировки, о которых большинство и не догадывается. В этой статье мы подробно разберём их.
Это также одна из ключевых тем на собеседованиях по системному проектированию. Интервьюер может задать вам вопросы о базовых концепциях или попросить продемонстрировать, как вы применяете балансировщики нагрузки и алгоритмы балансировки при проектировании масштабируемых систем — например, таких, как YouTube или Netflix.
Если вы готовитесь к таким собеседованиям и хотите глубже погрузиться в системное проектирование, стоит обратить внимание на ресурсы ByteByteGo, Design Guru, Exponent, Educative, Codemia.io и Udemy — на них есть множество качественных курсов и материалов.
Кроме того, существует отличный шаблон проектирования системы, в котором наглядно показаны ключевые компоненты архитектуры программного обеспечения — такие как API Gateway и Load Balancer. Его можно использовать в качестве основы при проектировании практически любой системы.
Виктор Корейша, автор подкаста «Кода Кода» комментирует:
На схеме и далее говорится о балансировке нагрузки, только как о распределении входящих унарных запросов. Это важная тема, которую стоит разобрать. Но для полноты картины отмечу, что если вы будете выстраивать систему, балансирующую нагрузку, которая представляет собой установку долгоживущих стримов, то есть ещё ряд особенностей, которые не упоминаются в статье. Кроме того, когда мы говорим о межсервисном взаимодействии, у нас появляется гораздо больше инструментов и гораздо больше требований, которые я также рекомендую изучить отдельно.
8 алгоритмов балансировки нагрузки, которые необходимо знать на собеседованиях по проектированию систем
1. Round Robin (Круговая система)
Алгоритм Round Robin циклически и равномерно распределяет входящие запросы между серверами в пуле. Он проходит по списку серверов последовательно — начиная с первого и заканчивая последним — а затем повторяет цикл, обеспечивая справедливое распределение трафика.
Преимущества:
- Простая реализация.
- Равномерное распределение запросов.
- Хорошо подходит для серверов одинаковой мощности.
- Предсказуемое поведение.
Недостатки:
- Не учитывает текущую загрузку серверов или сложность отдельных запросов, что может привести к дисбалансу в реальных сценариях.
Когда использовать: Round Robin наиболее эффективен в однородных серверных средах, где оборудование одинаковое, а входящие запросы примерно равны по сложности и требованиям к ресурсам.
Вот наглядная диаграмма, демонстрирующая работу алгоритмов Round Robin:
Виктор Корейша, Руководитель направления Managed Services в Ozon и автор подкаста «Кода Кода»:
При проектировании систем всегда важно смотреть не только на работу системы в стабильном состоянии, но и на ситуации сбоев. Или наоборот, обсуждать, как работает система при масштабировании — увеличении количества серверов.
Если вы используете RR при увеличении количества серверов, то они просто встают «в конец очереди» и новые запросы начинают лететь туда. Это значит, что если запросов не много, но они «тяжелые», а новые сервера не сразу станут такими же нагруженными, как старые.
Пример: каждый из трёх серверов обрабатывает сейчас 10 запросов (долгих). В нашу систему приходит 4 новых запроса в секунду. Мы добавляем четвёртый сервер. После первой секунды распределение нагрузки станет 11-11-11-1. Это может показаться пустяком при большом количестве запросов, но если есть зависимость, то мы получим цикл, в котором «старые» сервера всегда будут более нагружены, чем новые.
Другая проблема нас ожидает при ретраях — каждая новая попытка клиента отправить тот же самый запрос попадет на случайный сервер. А это значит, что мы не гарантируем, что один и тот же запрос не попробует обработаться одновременно на двух серверах. Это может вызывать проблемы в некоторых кейсах.
2. Least Connections (Наименьшее количество соединений)
Алгоритм Least Connections направляет входящие запросы на сервер, у которого в данный момент меньше всего активных соединений. Такой подход помогает распределять нагрузку более равномерно и предотвращает перегрузку отдельных узлов.
Преимущества:
- Учитывает текущее число соединений на сервере, а значит, гибче, чем простой Round Robin.
Недостатки:
- Не оценивает фактическую нагрузку в реальном времени и не учитывает сложность самих запросов.
Как отмечает Виктор Карпов, Software Engineer & Educator, автор канала coding_interviews: «в случае долгоживущих соединений (например, WebSocket) метрика "число соединений" может вводить в заблуждение».
Когда использовать: метод подходит для неоднородных серверных инфраструктур (разные мощности серверов), если входящие запросы примерно равны по сложности.
Вот наглядная диаграмма, показывающая, как алгоритмы наименьшего количества соединений распределяют нагрузку:
Виктор Корейша, Руководитель направления Managed Services в Ozon и автор подкаста «Кода Кода»:
Существенное значение имеет то, как именно считаются соединения. При использования этого алгоритма у вас могут быть проблемы с горизонтальным масштабированием самого балансировщика. Потому что если каждый балансировщик считает соединения независимо, то такой красивой картинки как выше уже не получится. Обычно это решается тем, что информацию о количестве соединений передают сами сервера. Важно, что тут учитываются только соединения, но не их параметры.
Например, если к одному из серверов пришёл один запрос, ответ на который выжирает всю сеть, то вы всё равно будете стараться отправлять туда новые запросы. В худшем случае это может привести к ситуации, когда все новые запросы летят в один сервер, который не может на них ответить.
3. Weighted Round Robin (Взвешенная круговая система)
Алгоритм Weighted Round Robin учитывает разную производительность серверов, присваивая каждому вес в зависимости от его мощности или доступных ресурсов.
Запросы распределяются пропорционально этим весам, что позволяет более мощным серверам обрабатывать большую долю трафика, а менее производительным — меньшую.
Преимущества:
- Учитывает различную производительность серверов.
- Прост в реализации и предсказуем в работе.
- Подходит для масштабирования без сложных расчётов.
Недостатки:
- Не учитывает динамическую загрузку в реальном времени.
- При резком изменении нагрузки возможна временная разбалансировка.
Когда использовать: подходит для инфраструктур с неоднородными серверами, где нужно учитывать их разную мощность, но нагрузка относительно предсказуема.
Виктор Корейша, Руководитель направления Managed Services в Ozon и автор подкаста «Кода Кода»:
Если вы расскажите об этом алгоритме на собеседовании, то, вероятно, последует вопрос — а как вы будете определять эти веса. И ответ на него очень не тривиален, потому что механизм определения зависит не только от типа нагрузки, но и от статистики ее распределения, как по запросам, так и по времени.
4. Weighted Least Connections (Взвешенные наименьшие связи)
Алгоритм Weighted Least Connections сочетает в себе подходы Least Connections и Weighted Round Robin. Он направляет входящие запросы на сервер с наименьшим отношением числа активных соединений к его весу, где вес отражает производительность или доступные ресурсы узла.
Это позволяет одновременно учитывать текущую загрузку и мощность сервера, добиваясь более точного распределения трафика.
Преимущества:
- Балансирует нагрузку с учётом как мощности, так и текущего состояния серверов.
- Более эффективно использует ресурсы в неоднородных средах.
- Подходит для динамически меняющейся нагрузки.
Недостатки:
- Реализация сложнее, чем у простых алгоритмов.
- Требует точных данных о весах и активных соединениях.
Когда использовать: идеален для инфраструктур с разной мощностью серверов и неравномерным распределением запросов, особенно если нагрузка часто меняется в реальном времени
5. IP Hash (IP-хэш)
Алгоритм IP Hash используется для балансировки нагрузки с сохранением постоянного соответствия между клиентом и сервером. Он вычисляет хэш на основе IP-адреса клиента (или комбинации IP-адреса клиента и назначения) и по результату хэш-функции выбирает сервер, на который будет отправлен запрос.
Это гарантирует, что все запросы от одного и того же клиента будут направляться на один и тот же сервер, что особенно важно для приложений, которые хранят состояние сессии на стороне сервера.
Важно замечание от CTO клиентского сервиса СберСтрахование Жизни Максима Чернухина: «Для микросервисов это скорее антипаттерн, поэтому я бы не рекомендовал использовать этот алгоритм без понимания, что он вам даёт».
Преимущества:
- Обеспечивает устойчивое закрепление клиента за сервером (session persistence).
- Упрощает работу с приложениями, где нельзя или неудобно хранить сессии централизованно.
- Простая реализация, не требует отслеживания соединений в реальном времени.
Недостатки:
- Возможна перегрузка отдельных серверов, если большое количество клиентов находится в одном диапазоне IP-адресов.
- При смене IP у клиента закрепление нарушается.
- Изменение пула серверов (добавление или удаление) может перераспределить клиентов, что приведёт к потере сессий.
Когда использовать: подходит, если важно закрепить клиента за конкретным сервером, а IP-адреса пользователей стабильны. Часто применяется в приложениях с отслеживанием состояния, например, интернет-магазинах или банковских сервисах.
Виктор Корейша, Руководитель направления Managed Services в Ozon и автор подкаста «Кода Кода»:
При изменении количества доступных серверов хеш будет пересчитан для всех. Почему-то, это часто не учитывают. А если наша система хранит какие-то состояния, то это может стать большой проблемой.
Представим, что мы выбрали такой алгоритм, т.к. при первом обращении клиента выкачиваем какие-то данные из базы и дальше приравниваем их в памяти. И чтобы минимизировать нагрузку на базу, мы придумали отправлять запросы одного и того же клиента (по IP) в один и тот же сервер. Но это значит, что при «мигании» сервера или сети мы как-минимум дважды должны будем пересоздать все сессии, для всех активных клиентов. То есть получить ту самую нагрузку, которую мы пытались избегать, но внезапно. То есть сэкономить на серверах для БД мы уже не можем — мы всегда должны держать полный запас.
Это только один из примеров того, что этот алгоритм часто не решает тех проблем, из-за которых на него переходили. Я не говорю о том, что так всегда, но чем сложнее алгоритм балансировки, тем больше корнер-кейсов нам важно учесть
6. Наименьшее время отклика (Least Response Time)
Алгоритм Least Response Time выбирает сервер для нового запроса, основываясь сразу на двух показателях:
- Количество активных подключений на сервере.
- Среднее время отклика сервера.
Балансировщик нагрузки отдает приоритет тем серверам, которые обрабатывают запросы быстрее и при этом менее загружены по количеству соединений. Это делает алгоритм особенно полезным для оптимизации производительности и повышения качества обслуживания пользователей.
Преимущества:
- Учитывает не только загруженность по соединениям, но и фактическую скорость работы сервера.
- Повышает отзывчивость системы, улучшая пользовательский опыт. Хорошо подходит для динамических сред с неоднородными серверами.
Недостатки:
- Более сложная реализация по сравнению с простыми алгоритмами вроде Round Robin или Least Connections.
- Требует постоянного мониторинга метрик времени отклика, что может увеличить нагрузку на балансировщик.
Когда использовать: идеален для систем, где скорость реакции критична, например, в стриминговых сервисах, финансовых приложениях, онлайн-играх или e-commerce-платформах, где задержки напрямую влияют на удовлетворенность пользователей.
Виктор Корейша, Руководитель направления Managed Services в Ozon и автор подкаста «Кода Кода»:
Посчитать время отклика — не такая тривиальная задача, как кажется. Если смотреть на время, например, последнего успешного запроса, то мы можем получить какой-нибудь выброс, после которого большое количество запросов пойдет на сервер, который единожды ответил быстро. Если смотреть, например, на p99, то тут вмешивается другая проблема — окно, по которому мы собираем эту статистику. Чем оно больше, тем хуже мы реагируем на всплески; а чем меньше, тем менее точную статистику мы получаем.
Другая сложность — сбор и хранение этой статистики. А еще тот факт, что статистика всегда будет «запаздывать» — мы же смотрим не нагрузку в моменте, а то, какие были ответы в некотором прошлом.
7. Случайный (Random)
Алгоритм Random распределяет входящие запросы случайным образом между серверами в пуле, без учета их текущей нагрузки, мощности или времени отклика.
Подход прост в реализации и не требует сбора метрик о состоянии серверов. Он часто используется как резервная стратегия или в случаях, когда система должна работать с минимальной логикой распределения.
Преимущества:
- Очень простая и быстрая реализация.
- Не требует мониторинга серверов или хранения статистики.Может быть полезен как временное решение или fallback-алгоритм при сбое основной логики балансировки.
Недостатки:
- Не учитывает текущую загруженность серверов, что может привести к перегрузке отдельных узлов.
- Эффективность сильно зависит от равномерности случайного распределения и однородности серверов.
Когда использовать: подходит для небольших систем с одинаковыми по характеристикам серверами, тестовых сред или как запасной механизм при отказе более сложных алгоритмов.
Виктор Корейша, Руководитель направления Managed Services в Ozon и автор подкаста «Кода Кода»:
При большом количестве запросов и едином балансировщике работает почти так же, как RR. Но вот если балансировщиков много или запросов мало, то статистика может быть весьма неожиданной.
8. Наименьшая пропускная способность (Least Bandwidth)
Алгоритм Least Bandwidth предназначен для распределённых систем, где ключевым фактором выступает не только вычислительная нагрузка, но и сетевые ресурсы. Он направляет новые запросы на сервер, который в данный момент потребляет минимальную долю доступной пропускной способности сети.
Такой подход особенно полезен в высоконагруженных системах с интенсивной передачей данных — например, в видеостриминге, CDN, системах онлайн-игр и облачных сервисах хранения.
Виктор Карпов, Software Engineer & Educator, автор канала coding_interviews: «Least Bandwidth подходит для балансировщиков L7, где есть доступ к информации о размере передаваемых данных».
Преимущества:
- Учитывает сетевую нагрузку, а не только вычислительные ресурсы.
- Помогает предотвратить узкие места в сети и задержки передачи данных.
- Обеспечивает более стабильную работу при пиковых нагрузках на канал.
Недостатки:
- Требует постоянного мониторинга сетевой статистики, что усложняет реализацию.
- Может быть избыточен для систем с небольшими объёмами передаваемых данных.
Когда использовать: применяется в проектах, где качество соединения и скорость передачи данных критичны для работы сервиса, например:
- Потоковое видео и аудио
- Онлайн-гейминг
- Сервисы облачного бэкапа
- Системы передачи больших файлов
Выводы
Балансировка нагрузки — один из ключевых инструментов системного проектирования, который напрямую влияет на производительность, надёжность и масштабируемость приложений. Знание различных алгоритмов помогает инженерам подбирать оптимальную стратегию распределения трафика под конкретные условия и требования бизнеса.
CTO клиентского сервиса СберСтрахование Жизни Максим Чернухин отмечает, что почти все из данных методов будут успешно работать на HTTP 1.1:
Но необходимо помнить, что если в вашем случае протокол HTTP 2.0 нужно реализовывать подобными алгоритмами на уровне L7, вам придётся расшифровывать трафик TLS, чтобы получить больше информации о запросах.
Так происходит потому, что для HTTP 1 для каждого запроса создаётся новое соединение. И в момент создания этого соединения можно предусмотреть работу с выбором сервера, на который будет отправлен запрос. А вот в случае HTTP 2, новый запрос отправляется в рамках существующего соединения.
Это значит: раскрыв само соединение, мы не сможем увидеть, что один клиент отправляет 1000 запросов в рамках него, а другой клиент отправляет в рамках своего соединения всего 10 запросов.
Простые алгоритмы (Round Robin, Random) подходят для однородных сред и минимальных требований к производительности.
Как отмечает Дмитрий Зайцев, CTO Flocktory, программный директор DevOpsConf, чаще всего встречается всё-таки Round Robin:
На самом деле, даже системы, где есть неоднородные среды и большие требования к производительности — тысячи и сотни тысяч запросов в секунду — живут с Round Robin. Ну или его взвешенной версией и не переживают. Другие подходы нужны скорее для решения каких-то конкретных проблем с трафиком и балансировкой.
1К открытий4К показов














