Вспомним немножко, что же это такое — сети дата-центров?
В целом, наверное, уже второе десятилетие, как вся индустрия сетевой инженерии и сетевой архитектуры пришла к тому, что сети в дата-центрах перешли от так называемой “классической трёхуровневой архитектуры” (где у нас есть железки уровня доступа, железки уровня агрегации, кор и какой-то внешний выход) к сетям Leaf-Spine (или она же Clos-архитектура).

Leaf-Spine – ну очевидно, потому что есть листья (Leaf), потому что есть хребты (Spine), есть супер-хребты, и всё такое. Думаю, всем, кто хоть раз вводил в гугле или спрашивал у своего старшего (или у младшего, более свежего, товарища) “сеть дата-центра”, скорее всего, выдавалась какая-то такая картинка.
Итак, почему в принципе Clos? Почему индустрия пришла к этому? Какие преимущества есть у данной топологии?
-
Первое, что приходит в голову, — конечно, масштабируемость. Топология позволяет легко добавлять какие-то новые устройства, увеличивать пропускную способность без изменения архитектуры. Появились у нас какие-то новые сервера? Вот здесь вот мы поставили новый свич, ткнули его сюда, подняли LACP. По факту, с точки зрения архитектуры, ничего не изменилось, но мы таким образом увеличили количество серверов, которое можем обслуживать.

-
Второе — это большое количество элементов, которые друг друга дублируют. Это сделано не просто так. Это сделано как раз для отказоустойчивости. Отвалилось там, отвалилось сям — ничего страшного, трафик пойдёт эдак. Отвалился вот этот — тоже ничего страшного. Отвалился этот — и это переживём. Сеть становится отказоустойчивой.

-
Линки, которые здесь нарисованы, могут утилизироваться одновременно — в этом преимущество. Обычно это какая-то IP-фабрика, где у нас используется протокол динамической маршрутизации, который позволяет использовать несколько путей одновременно, в отличие от какого-нибудь мутный STP, который блокирует линки.
-
Универсальность. Да, так как это IP-фабрика, поверх этой IP-фабрики могут бегать любые сервисы. Это могут быть разные VPN, там GRE, вы можете запускать разные VXLAN и так далее, и тому подобное. То есть IP-фабрика строится под любой тип сервиса, который уже, например, в виде оверлейной сети может доставлять трафик до конечного сервиса.
-
Часто упоминают некую “экономическую эффективность”, но тут вызывает вопросики, потому что, конечно, это всё надо считать. Пунктик такой спорный.
Ну а вообще, сети сами по себе мало кому интересны — всем важны сервисы, которые они поддерживают. Как сетевые архитекторы и инженеры, мы всегда должны помнить, что людям важны именно сервисы. А чтобы эти сервисы работали, нужны сети. Вот такая простая логика.
А что же нужно сервисам (помимо сети, конечно)? Как ни странно, сервисам нужно всё то же самое.
-
Лёгкость масштабирования: Например, если мы создаём сайт с котиками и у нас появляется много пользователей, нам нужно добавить ещё один сервер и распределить трафик с помощью балансировки. Инфраструктура должна легко поддерживать это. С увеличением количества пользователей должно расти и количество хранилищ данных, так как хранилище — это тоже сервис, который должен уметь масштабироваться.
-
Отказоустойчивость: Если мы сделали сайт с котиками, и один сервер вышел из строя, пользователи всё равно должны иметь доступ к своим котикам. Даже если целый дата-центр перестанет работать, пользователь не должен это заметить — ему важны котики.
-
Эффективное использование ресурсов: Здесь на помощь приходят облачные технологии. Почему облачные вычисления стали популярными? Благодаря гибкости управления ресурсами. Сегодня у вас 10 пользователей, завтра 100, а послезавтра снова 15. Нужно уметь гибко масштабироваться. Для этого используются контейнерные технологии и другие современные облачные решения.
Деплоим сайт с котиками

Итак, если мы решили создать сайт с котиками и хотим, чтобы он был масштабируемым и надёжным, какие шаги нужно предпринять для обеспечения его отказоустойчивости?
-
Добавляем пачку серверов с фотографиями котиков
-
Делаем отказоустойчивость на уровне датацентрарегиона
-
Делаем геораспределение по всему миру
-
Настраиваем балансировку
-
???
-
PROFIT
Тут начинают возникать вопросики…
Вот, допустим, мы сделали инфраструктуру, которая хостит наших котиков:

Как пользователю добраться до сайта с котиками если серверов несколько?
Пользователь приходит в датацентр, и чё? Куда ему идти? До этих котиков?

Или до вот этих вот?

И если до вторых котиков, то как конкретно пробраться туда? Вот так?

Или вот так вот?

Но допустим, мы эту проблему каким-то образом решили.
Как пользователю добраться до сайта с котиками если датацентров несколько?
Ведь дальше мы начинаем масштабироваться – нам становится тесно в датацентре, ещё и эти стойки по 5КВатт всего. Делаем какой-то мультизональный котиковый сайт. Каждая зона – это датацентр в одном регионегороде. Какой-то DataCenter Interconnect (DCI) между ними – тёмная оптика, крашенная оптика, L2 VPN, не важно:

Куди идти за котиками? Непонятно :(
Как пользователю добраться до сайта с котиками если котики разбросаны по миру?
С котиками всегда происходит одно и тоже – они очень популярны! И ваши котики теперь востребованы по всем миру. Нужна мировая экспансия вашего гениального сайта про котиков – делаем регион в Штатах, Европе, Ботсване и, конечно, Магадане!

Куда пойти гордому кахазу смотреть котов? А?
Попытаемся решить наши вопросики
А давайте попробуем попытаться решить возникшие вопросики. Да, как нам трафик то доставить?
В какой регион пригнать трафик пользователя?
Итак у нас есть пользователи в Казахстане, есть сайты с котиками, разбросаные по всему миру. Что собственно можно делать?

1. Можно вообще не заморачиваться. Просто анонсируем наш публичный IP через BGP без всяких политик и смотрим, что получится. Какая-никакая балансировка всё равно возникнет: часть трафика пойдёт в один дата-центр, часть — в другой. Но если кто хоть раз работал у провайдера или просто шарит, как устроен интернет — говорить тут про ‘оптимальное распределение’ как-то… ну, смешно. Скорее всего, всё перекосит: какие-то дата-центры начнут жрать львиную долю трафика, а остальные так и останутся полупустыми.
2. Второй вариант — раскидываем IP по миру. Берём четыре адреса: один анонсируем из Штатов, второй — из Европы, ну и из Ботсваны и Магадана тоже. Прописываем их в DNS как 4ре A-записи с одним именем (round-robin сделает своё дело). Плюсы – трафик в теории распределится плюсминус равномерно между регионами. Минус – DNS-рулетка скорее всего будет стрелять криво, и жителю Ботсваны придётся пиздовать за котиками в Магадан :(
3. Самый толковый вариант — глобальные балансировщики (GSLB). Это умный DNS, который смотрит откуда клиент и подсовывает ему ближайший дата-центр: Казахстан — Европа, Канада — Штаты. Вроде бы идеально, но на практике всё равно придётся постоянно мониторить и подкручивать — трафик любит течь не туда, куда планировалось. Зато если настроить — будет работать лучше любого round-robin’а. Вот таким образом пользователь, находясь в Казахстане, скорее всего, придёт куда-то в Европу. Находящийся в Канаде, скорее всего, придёт куда-то в США.
В какой датацентр в регионе пригнать трафик?
Теперь нам нужно доставить трафик внутри региона. Здесь в принципе методы балансировки те же самые.

1. Не делать в принципе ничего — положиться на дикий BGP. Просто анонсируем из дата-центров один и тот же IP и смотрим, что получится) Авось как то разбаланисируется – главное стыки со всякими разными операторами заиметь в разных местах
2. Второй вариант — снова играем в DNS-рулетку, но уже внутри региона. Раздаём каждому дата-центру свой уникальный /24 и общий резервный /22. Если один ДЦ отвалится — трафик автоматически перекинется на остальные через общую сеть. Работает? Вроде да. Идеально? Ну…
3. Третий вариант — пусть трафик идёт в любой дата-центр региона, будь то Ховрино или Бутово. Разницы нет — главное, что он в нашей сети. А дальше в дело вступает какой-нибудь MPLS TE: он автоматически раскидает трафик между дата-центрами пропорционально их мощностям. Если в одном ДЦ два рабочих сервера, а в другом один — то первый получит две трети трафика, второй оставшуюся треть. Никакой магии — просто умная система сама поддерживает баланс по количеству активных серваков. Реализация – дело ваше – моё дело предложить гениальную идею xD
В общем, здесь тоже есть варианты и трафик в датацентр мы, допустим, доставили.
До какого сервера доставить трафик внутри датацентра?
А что можно сделать здесь? До какого сервера доставить трафик внутри дата-центра?

1.Опять таки – не делаем НИХУЯ НИЧЕГО*, а полагаемся на чистый рандом (утрировано) и отработку стандартных механизмов ECMP в фабрике, используя anycast – все сервера доступны по одному и тому же IP. Однако есть нюанс- если сервис сдох, а сервер ещё дышит и рассказывает об этом в сеть, трафик будет проливаться в чёрную дыру. Никакой проверки состояния живости сервисов нету :(
*Но да, если у вас в фабрике BGP – ECMP, скорее всего, придётся включить и слегка подтюнить )
2. Добавляем немного мозгов балансировке – ставим какой-нить L3L4 балансировщик. Самое дешёвое что приходит в голову – базовый модуль ядра Linux под названием IPVS с базовыми keepalived-проверками. Теперь нам хотябы понятно, кто реально жив и готов принять трафик, а кто просто машет из гроба своим IP-адресом. Мозгов хоть и добавили, но всё равно балансировка туповата – оперируем только IP и портами, а что внутри пакетов — не понятно.
3. Добавляем к пункту 2 какой-то Application балансировщик. Вот тут уже настоящая магия: NGINX или HAProxy ковыряются в HTTP-трафике. Хочешь — раскидывай запросы по URL (/cats — на один кластер, /dogs — на другой). Хочешь — привязывай пользователей к серверам через куки. SSL? Оффлоадим прямо тут! – бекенду и так хватает проблем. Минус один – всё это надо уметь готовить )
Идеальная иерархия балансировки в дата-центре

1. Входная дверь (ECMP + Anycast)
Трафик пользователя залетает в фабрику через обычный IP-роутинг. ECMP раскидывает его по L3/L4 балансировщикам (NLB) по простому советскому роутингу. Anycast позволяет всем NLB отвечать с одного IP. Просто и эффективно, но без мозгов.
2. Среднее звено (L4 → L7)
Здесь начинается магия:
-
NLB (L3/L4) принимает трафик и строит туннель (GRE/IPIP) до ALB
-
Проверяет здоровье сервисов через health checks
-
Может использовать DSR для обратного трафика (пакеты идут в обход NLB)
-
Распределяет нагрузку между кучей Application LB
3. Финиш (L7-балансировка)
ALB работают с прикладным уровнем:
-
Разбирают HTTP/HTTPS как заправские криптоаналитики
-
Маршрутизируют по URL (/cats → cluster1, /dogs → cluster2)
-
Оффлоадят SSL
-
Поддерживают sticky sessions через куки
И это хорошо
-
Гибкая масштабируемость: можно добавлять слои NLB/ALB
-
Оптимальный путь: DSR сокращает нагрузку на NLB для обратного трафика
-
Фатальные ограничения: упрётесь только в физику (провода, мощность серверов)
Масштабируем!
-
Городской уровень (Бутово, Щукино и др.)

-
Международный уровень

-
Континентальные точки присутствия (Европа, Азия, США)
-
Тот же принцип, но с доп. слоями:
-
Гео-DNS (клиент из Берлина получает IP франкфуртского ДЦ)
-
Межконтинентальные Anycast (BGP + локализованные anycast-IP)
-
Глобальный GSLB с учётом:
-
Задержек между континентами
-
Юридических ограничений (GDPR в ЕС)
-
Цены на транзит в регионе
-
-
“Это. Просто. Охуенно.” (с) Анонимный сетевой инженер
-
Примеры балансировщиков

1. L7 (Application Load Balancers) :
a. Nginx
b. HAProxy
c.Traefik
d.Envoy
e.Istio (Service Mesh)
2. L3/L4 (Network Balancers):
a. IPVS (LVS)
b. F5 BIG-IP
3. Облачные решения:
a. AWS ALB
b. GCP HTTP(S) LB
c. Azure Application Gateway
Дальше была идея сделать небольшое практическое “демо” как сделать простейшую балансировку в лабе с помощью ECMP+Anycast+Linux IPVS, но мне лень. Делайте сам
Проблемы и вопросы сетевой (ECMP) балансировки
Дальше напишу немножко про НЮАНСИКИ которые стоит помнить при работе с ECMP
ЖУТКИЙ ДИСКЛЕЙМЕР. ЛУЧШЕ НЕ РАСКРЫВАЙТЕ
Базу для этой статейки я готовил достаточно давно, а написав всё и оформив я ОСОЗНАЛ, что эта часть статьи ПОВТОРЯЕТ статью Марата!
Я НЕ ХОТЕЛ, ТАК ПОЛУЧИЛОСЬ. Где-то на подкорке отложилось. В общем, изложение своими словами получилось со знатной долей чудной отсебятины
Кто кандидат на равнозначность?
А как вообще включить эту самую ECMP, как маршрутам попасть в группу счастливчиков? Требований не много на самом деле
-
Оборудование должно поддерживать ECMP в принципе. Наверное мало кто НЕ поддерживает в 2025-м то.
-
Маршруты должны быть из одного протокола маршрутизации. При этом протокол маршрутизации должен поддерживать multipath. Ну стоит помнить что например у OSPFISIS – это дефолтная опция, а у BGP – не всегда*
-
Маршруты должны иметь одинаковую стоимость с точки зрения протокола.
BGP “со звёздочкой”, потому что не везде multipath для него включен, ну и в кейсах когда у вас eBGP в фабрике стоит помнить про bgp multipath as-path relax
Куда пакет-то отправлять?
Ок, ну допустим ECMP мы включили-настроили, и вот в такой схеме у нас два возможных пути:
Когда перед коммутатором два “равнозначных” пути, возникает ключевой вопрос: по какому принципу распределять трафик? Варианта два — оба с подводными камнями.
Варианта по-сути два:
-
Per-packet. Каждый пакет по round-robin раскладывается то в один порт, то в другой.
И для некоторых кейсов это может быть даже ок:

Если сеть стабильна, с предсказуемой задержкой, то наверное это даже бОльшую равномерность даст.
Но как только придёт TCP ANYCAST…

Потому норм пацаны юзают вариант два
-
Per-flow. Считается хеш от параметров потока:
-
MAC-addresses + EtherType для L2
-
5 tuple для udptcp
-
То есть у нас вот по такой простой картинке считается некий Хеш:

Этому хешу ставится в соответствие некий выходной порт. Дальше приходит пакетик, для него ещё раз считается хеш и если параметры потока не поменялись – хеш получается тот же самый, а у нас уже есть для него выходной интерфейс – ну туда его и отправим. А если про поток ничего не известно было заранее – отправим в новый порт и в табличку запишем. В итоге трафик в рамках одной и той же tcp сессии. Будет всегда идти в один и тот же интерфейс… Ну как “всегда”…
Вот есть у нас девственно чистая безпоточная сеточка:

Три выходных интерфейса, хешей нет, табличка пуста. Приходит первый поток, посчитали хеш, решили положить его в первый интерфейс, заполнили табличку:

Потом ещё пару пацанов пришло:

Равномерно распределили, в общем, а потом ещё подъехали ребята:

Казалось бы, что может пойти не так? Может, например, какая-нибудь фигня произойти в сети. А фигни в сети происходят постоянно – это норма. Ну в общем, потерялся вот у нас один балансировщик из сети – сломался малый. Так у нас вся эта наша табличка по пизде пойдёт – ПОРТ ВЫПАЛ ИЗ БАЛАНСИРОВКИ, АААА, МИР ПЕРЕВЕРНУЛСЯ, СРОЧНО ВСЁ ПЕРЕСЧИТАТЬ.

Только 4-му потоку повезло оказатся в тойже корзинке.Непрятная ситуация – tcp сессии текущие почти все развалились, котики не докачались :( И щито делать?
Resilient Hashing
В целом, умные дядьки давно уже всё придумали и обозвали это “неунывыющий хэшинг”. Подробно наверное, можно почитаться вот туть – https://docs.nvidia.com/networking-ethernet-software/cumulus-linux-41/Layer-3/Equal-Cost-Multipath-Load-Sharing-Hardware-ECMP/ Я немного вкратце скажу про это, своровав картинки оттуда же. Итак, вот произошёл у нас такой кейс, было 4-ре выходных интерфейса, один сломался:

Первое правило консистентного хеширования – не трожь рабочие потоки! Заполни место выпавшего next-hop-а живыми:

Итоге – рабочее не ломаем, сломавшееся чиним. Занятно, но проблема становится более “проблемной” когда речь не про сломавшийся путь, а про новый next-hop, который надо вклинить в табличку, расталкав существующие потоки:

То есть появление нового балансировщика привносит больше проблем чем сломанный старый! В общем, будьте аккуратней, ребята, не деплойте новые балансировщики в ЧНН и избегайте флапов!)
Поляризация трафика
Ещё одна вещичка, про которую уже все забыли. Обычно, фабрику строят на оборудовании одного и того же вендора, и даже если это разные железки, логика расчёта хеша и сопоставление хеша некст-хопу может быть одинаковая. Поэтому вполне вероятен такой кейс. Приходит, значит поток на нижний коммутатор и по ECMP раскладывается влево:

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

Второй поток придя в фабрику разложится направо:

И ещё раз направо:

Третий поток допустим разложится пару раз в лево:

Чуете чем пахнет, А?

Чуете?

Пахнуло ПОЛЯРИЗАЦИЕЙ. Ну а для решения проблемы с неприятным запахом нужна простая советская…

Умные инженеры подмешивают в хеш уникальный параметр (обычно кусок системного MAC-адреса) – после этого результат работы хеш функции будет разным и как следствие выходные порты – тоже.
И последнее.
Когда мы наконец решили проблемы с правильным хешированием и распределением наших потоков и посыпали всё солью, решив проблему поляризации приходят они….

…снова.
Кто-то?
Мыши, говорю (mouse flows):
Это короткие, небольшие по объему потоки данных, которые обычно состоят из небольшого количества пакетов. Они часто представляют собой запросы и ответы, такие как веб-запросы или небольшие транзакции. Эти потоки чувствительны к задержкам, поэтому важно, чтобы они обрабатывались быстро и с минимальными задержками.
И слоны (elephant flows):
Это длинные, большие по объему потоки данных, которые могут занимать значительную часть пропускной способности сети. Они обычно состоят из большого количества пакетов и могут представлять такие задачи, как передача больших файлов или резервное копирование данных. Эти потоки могут создавать заторы в сети, если их не обрабатывать должным образом.
Почему это вообще проблема?
(и тут я понимаю что пора научится делать GIF-ки) В общем, смотрим за картинками, опять. Первой пришла мышка. Отправили её вверх.

Потом пришёл слон. Его поток разложился вниз:

Потом слон, и ещё один слон. Распределили

В итоге слонов и мышей набежало так, что по количеству потоков мы, кажется, линки нагрузили равномерно, но вот по “тяжести” потоков как то не очень :(

Как же усмирить слонов и не раздавить мышей?
Вводим новый термин – flowlet и балансируем по ним!
Flowlet — это “кусочек” TCP-потока, разделённый естественными паузами (например, пока клиент обрабатывает данные и не выслал ACK) от других таких же кусочков. В общем иногда, TCP ничего не делает )

В отличие от классического ECMP, который тупо хеширует весь поток и ведёт его одним путём до конца, flowlet-балансировка ловит эти паузы и использует их для перераспределения трафика на менее загруженные пути. То есть хоть flow и один – его кусочки (те самые flowlet-ы) летают по разным путям в фабрике! Ничёси!
Тут условие только одно – главное чтобы фловлет номер 2 не прилетел раньше первого – иначе вообще фигня получится! Теоретически, такое может произойти если свитч решил отправит flowlet номер один через Австралию например (фигасе у вас фабрика!) – ну то есть по пути, задержка которого по сравнению с задержкой пути для второго флоулета, больше длительности паузы между ними. Ещё раз на пальцах:
-
Допустим предполагаемая пауза между фловлетами – 50 мкс
-
Для фловлета один выбран путь, по которому он приедет на 80 мкс
-
Для фловлета два выбран путь, который достави его за 20 мкс
В момент времени t0 мы отправили фловлет номер 1 в путь. Он прибудет через 80 мкс. Подождали 50 мкс и отправили фловлет номер два в путь. Относительно момента t0, фловлет два приедет до хоста через 50+20 мкс = 70 мкс. То есть на 10 мкс раньше чем фловлет номер 1. Хотел сделать лучше, а получилось как всегда :(
В общем, идея хорошая но наша сеть тут должна обладать недюжим интеллектом:
-
Нужно понимать вообще чё по латенси на альтернативных путях.
-
Нужно уметь предсказывать длину пауз от только что прибывшего кусочка до следующего. Выглядит как задача для AI, ну то есть для серьёзной математики. Ознакомится с серьёзностью математики предлагаю вот тут – https://www.eecs.umich.edu/courses/eecs589/papers/p503-alizadeh.pdf или вот тут – https://groups.csail.mit.edu/netmit/wordpress/wp-content/themes/netmit/papers/texcp-hotnets04.pdf Я такое не читаю, так как меня даже такие формулы начинают пугать в сетях

Вторая ссылка – один их первых документов по концепции фловлетов вообщем, первая – это про механимз CONGA, который является математической основой для цисковской реализации всей это магии, которая называется Dynamic Load Balancing и применяется в ACI. Ну кстати, да, кажется в SDN-е таким вещам самое место. А вот Juniper не парится и вполне себе несёт это всё в железную фабрику, обозвав Адаптивная Балансировка. Juniper молодец – будь как Juniper!
Ах, да кажется что применять такой подход для среды с Anycast-овыми сервисами стоит с некоторой осторожностью – не факт что ваша фабрика в теме, что за разными путями могут скрываться РАЗНЫЕ сервера – в итоге ваши TCP сессии будут регулярно разваливаться с таким подходом. Но я хз – я лично такое в проде пока не встречал, в основном теоретизирую тут. Встречал ли кто-то? Мне кажется нет и это всё пиздёшь)
ВЫВОДЫ
-
Помнить что серебряной пули нет
-
Анализировать ваши требования к сервису, ваш паттерн трафика
-
Применять гибридные подходы – на каком-то участке использовать один тип балансировки, где-то другой
-
Изучать и исправлять ошибки
Всё, расходимся. Тут не на что больше смотреть. А побольше смотреть есть тут
Автор: paralon


