Главная » Хабрахабр » Варианты применения или чего не хватает балансировщикам нагрузки

Варианты применения или чего не хватает балансировщикам нагрузки

Пару лет назад я завершил проект миграции в сети одного из наших клиентов, задача заключалась в смене платформы, которая осуществляет распределение нагрузки между серверами. Схема предоставления сервисов этого клиента эволюционировала в течении почти 10-ти лет вместе с новыми разработками в индустрии ЦОД, поэтому «придирчивый», в хорошем смысле этого слова, клиент ожидал решения, которое удовлетворяло бы не только требованиям отказоустойчивости сетевого оборудования, балансировщиков нагрузки и серверов, но и обладало бы такими свойствами как масштабируемость, гибкость, мобильность и простота. В этой статье я постараюсь последовательно, от простого к сложному, изложить основные примеры использования балансрровщиков нагрузки без привязки к производителю, их особенности и методы сопряжения с сетью придачи данных.
Балансировщики нагрузки сейчас все чаще называют контроллерами доставки приложений (Application Delivery Controller — ADC). Но если приложения работают на сервере зачем их куда-то доставлять? Из соображений отказоустойчивости или масштабирования приложение может быть запущено более чем на одном сервере, в этом случае нужен своего рода обратный прокси-сервер, который спрячет от потребителей внутреннюю сложность, выберет нужный сервер, доставит на него запрос и проследит за тем, чтобы сервер вернул корректный, с точки зрения протокола, результат, иначе — выберет другой сервер и отправит запрос туда. Для осуществления этих функций ADC должен понимать семантику протокола прикладного уровня, с которым он работает, это позволяет настраивать appication specific правила доставки трафика, анализа результата и проверки состояния сервера. Например, понимание семантики HTTP, делает возможной конфигурацию, когда HTTP запросы

1
Host: www.company.com
Accept-Language: en-us
Accept-Encoding: gzip, deflate
GET /docs/index.html HTTP/1.

отправляются на одну группу серверов с последующим сжатием результатов и кешированием, а запросы

1
HOST: b2b.company.com
X-Auth: 76GDjgtgdfsugs893Hhdjfpsj
Content-Type: application/json
POST /api/object-put HTTP/1.

обрабатываются по совершенно другим правилам.

Даже работая без понимания семантики протокола прикладного уровня ADC может быть полезен для решения тех или иных задач, так например я принимал участие в построении самодостаточной виртуальной фермы SMTP серверов, в период спам-атак количество экземпляров увеличивается с помощью управления с обратной связью по длине очереди сообщений, чтобы обеспечить удовлетворительное время проверки сообщений ресурсоёмкими алгоритмами. Понимание семантики протокола позволяет организовывать сессионность на уровне объектов прикладного протокола, например, с помощью HTTP Headers, RDP Cookie, или осуществлять мультиплексирование запросов чтобы заполнять одну транспортную сессию многими пользовательскими запросами если прикладной уровень протокола позволяет это делать.
Сферу применения ADC иногда неоправданно представляют себе только обслуживанием HTTP трафика, на самом деле список поддерживаемых протоколов у большинства производителей гораздо шире. В случае SMTP такая схема работы была вполне оправдана из-за высокой энтропии соединений на сетевом и транспортном уровнях, для равномерного распределения нагрузки во время спам-атак ADC требуется только поддержка TCP. Во время активации сервер регистрировался на ADC и получал свою порцию новых TCP сессий. Углубляться в тему особенностей протоколов дальше я не буду, этот аспект слишком обширен чтобы излагать его во вступлении, если что-то покажется интересным — пишите, возможно это повод для статьи с более глубоким изложением какого-то варианта применения, а теперь перейдем к сути. Похожая схема может применяться для построения фермы из серверов баз данных, высоконагруженных кластеров DNS, DHCP, AAA или Remote access серверов, когда сервера можно считать равнозначными в предметном домене и когда их характеристики производительности не слишком сильно отличаются друг от друга.

Чаще всего ADC замыкает на себя транспортный уровень, поэтому сквозная TCP сессия между потребителем и сервером становится составной, потребитель устанавливает сессию с ADC, а ADC — с одним из серверов.

1 image
Рис.

Самый простой вариант заставить трафик первой части прийти на ADC заключается в присвоении адресу сервиса одного из интерфейсных адресов ADC, со второй частью возможны такие варианты:
Конфигурация сети и настройки адресации должны обеспечивать такое продвижение трафика чтобы две части TCP сессии прошли через ADC.

  1. ADC как default gateway для серверной сети;
  2. трансляция на ADC адреса потребителя в один из своих интерфейсных адресов.

На самом деле чуть более реалистичный вид первой схемы применения выглядит уже вот так, это базис, с которого мы начнем:

2 image
Рис.

Эта группа серверов может представлять собой отдельный домен маршрутизации, со своими политиками, располагаться в другом ЦОД или вовсе быть изолированной из соображений безопасности. Вторая группа серверов может быть базами данных, бек-эндами приложений, сетевыми хранилищами или фронт-эндами для другого набора сервисов в случае декомпозиции классического приложения на микро-сервисы. Коммутаторы на рисунке 2 не обязательно физические — домены маршрутизации можно реализовать с помощью виртуальных сущностей, которые у разных производителей называются virtual-router, vrf, vr, vpn-instance или виртуальная таблица маршрутизации.
К слову сказать, есть и вариант сопряжения с сетью, без требования к симметричности потоков трафика от потребителя к ADC и от ADC к серверам, он востребован в случаях долго живущих сессий, по которым в одну сторону передается очень большое количество трафика, например, стриминг или вещание видео контента. Сервера редко находятся в одном сегменте, чаще их помещают в сегменты по функциональному назначению с четко регламентированными политиками доступа, на рисунке это изображено в виде файервола.
Исследования показывают, что современные многоуровневые приложения генерируют больше West-East трафика, и вам вряд ли захочется чтобы весь внутрицодовый/межсегментный трафик проходил через ADC. Обратный трафик от сервера к потребителю идет, минуя ADC в соответствии с таблицей маршрутизации сервера. В этом случае ADC видит только поток от клиента к серверам, этот поток доставляется на интерфейсный адрес ADC и после простой обработки, которая заключается в замене MAC адреса на интерфейсный MAC одного из серверов, запрос отправляется на сервер где сервисный адрес присвоен одному из логических интерфейсов. Поддержка единого широковещательного домена для всех фронт-эндов может быть очень сложна, к тому-же возможности ADC по анализу ответов и поддержки сессионности в этом случае весьма ограничены, по сути это просто свитчинг, поэтому такой вариант далее не рассматривается, хотя в решении некоторых узких задач может быть использован.

3 image
Рис.

Итак, у нас есть один базис-ЦОД, изображенный на рисунке 2, давайте подумаем какие проблемы могут подтолкнуть базис-ЦОД к эволюции, я вижу две темы для анализа:

  1. Предположим, что коммутационная подсистема полностью зарезервирована, давайте не задумываться, как и чем, тема слишком обширная. Приложения работают на нескольких серверах и резервируются с помощью ADC, но как зарезервировать сам ADC?
  2. Если анализ показывает, что следующий сезонный пик нагрузки может превзойти возможности ADC, вы, само собой, задумаетесь о масштабируемости.

В то же время отказоустойчивость можно организовать по схеме Active/Backup и Active/Active, а масштабирование только по схеме Active/Active. Эти задачи похожи тем что, в процессе их решения количество экземпляров ADC точно должно увеличится. Активный ADC передает сервисные префиксы вышестоящему маршрутизатору, и принимает от него default маршрут для заполнения им своей таблицы и для передачи в сторону ЦОД в соответствующую виртуальную таблицу маршрутизации. Давайте попробуем решить их по отдельности и посмотреть какими свойствами обладают разные решения.
ADC многих производителей могут быть рассмотрены как элементы сетевой инфраструктуры, RIP, OSPF, BGP – все это там есть, а значит можно построить тривиальную схему Active/Backup резервирования. Сервера при таком подходе могут видеть реальный IP адрес потребителя, так как нет причин использовать трансляцию адресов. Резервный ADC выполняет все тоже самое, но, используя семантику выбранного протокола маршрутизации, формирует менее привлекательные анонсы. Эта схема работает также изящно в случае если вышестоящих маршрутизатор больше одного, но, чтобы избежать ситуации, когда активный ADC теряет default и связность с маршрутизатором, при этом все еще получает default от резервного ADC и продолжает анонсировать его в сторону ЦОД, постарайтесь избегать соседства между ADC и применение статических маршрутов.

4 image
Рис.

В случае более чем одного вышестоящего маршрутизатора нужно позаботиться о том, чтобы входящий трафик приходил более-менее равномерными порциями. Если на серверах не обязательно оперировать реальными IP адресами потребителя, или протокол прикладного уровня позволяет внедрять его в заголовки, как например HTTP, схема превращается в Active/Active с почти линейной зависимостью производительности от количества ADC. Эту задачу просто решить если в домене маршрутизации ECMP передача начинается до этих маршрутизаторов, если это затруднительно или если домен маршрутизации вами не обслуживается — можно использовать full-mesh соединения между ADX и маршрутизаторами, чтобы ECMP передача начиналась прямо на них.

5 image
Рис.

Решения этих задач обладают разным уровнем утилизации ресурсов, если вы проектируете Active/Standby схему, нужно смириться с тем что половина ресурсов будет простаивать. В начале этой части я написал, что отказоустойчивость и масштабирование — две большие разницы. Допустим вам необходимо обеспечить производительность 8 условных единиц (8 тыс. А если так сложится что вам понадобиться сделать очередной количественный шаг, будьте готовы в будущем умножать требуемые ресурсы еще на два.
Преимущества Active/Active начинают проявляться, когда вы оперируете количеством устройств большим двух. Если перевести эти цифры в ресурсы, которые простаивают получается треть против половины. соединений в секунду, или 8 млн одновременных сессий) и предусмотреть сценарий отказа одного устройства, в варианте Active/Active вам достаточно трех экземпляров ADC с производительностью по 4, в случае Active/Standby — двух по 8. С увеличением количества Active/Active экземпляров математика становится еще приятнее, а система получает возможность плавного увеличения производительности вместо ступенчатого Active/Standby. Тот же принцип расчета можно использовать для оценки доли разорванных соединений в период частичного отказа.

Но будет не очень корректно уделять этому много времени, так как я старался писать о подходах, а не об особенностях производителей. Будет корректно упомянуть об еще одном способе Active/Active или Active/Standby схем работы — кластеризации. При выборе такого решения нужно четко понимать следующие вещи:

  1. Кластерная архитектура иногда накладывает ограничения на ту или иную функциональность, в каких-то проектах это принципиально, в каких-то может стать принципиально в будущем, тут все сильно зависит от производителя и каждое решение нужно прорабатывать индивидуально;
  2. Кластер зачастую представляет из себя один fault domain, ошибки в программном обеспечении есть у будут.
  3. Кластер легко собрать, но очень сложно разобрать. Технология обладает меньшей мобильностью — вы не можете управлять частями системы.
  4. Вы попадаете в цепкие объятия своего производителя.

Тем не менее есть и положительные вещи:

  1. Кластер просто инсталлируется и просто эксплуатируется
  2. Иногда вы можете ожидать близкую к оптимальной утилизацию ресурсов.

Сделать это в существующем ЦОД не всегда возможно, поэтому предположим, что появилась новая просторная локация с дополнительными серверами. Итак, наш ЦОД с рисунка 5 продолжает расти, задача, которую вам, возможно, придется решать, заключается в увеличении количества серверов.

6 image
Рис.

Более общий случай, который не исключает появление площадки в другом городе или в другой стране, поставит перед ЦОД новые проблемы: Новая площадка может находится не очень далеко, тогда вы успешно решите задачу методом продления доменов маршрутизации.

  1. Утилизация каналов между площадками;
  2. Разница времени обработки запросов, которые ADC отправил на обработку близким и далеким серверам.

Размышление об этом подтолкнет вас к построению географически распределенной конфигурации ЦОД. Поддержание широкого канала между площадками может оказаться весьма затратным мероприятием, к тому же выбор места размещения перестанет быть тривиальной задачей— перегруженная площадка с маленьким временем отклика или свободная с большим. Эта конфигурация, с одной сторону, дружественна по отношению к потребителям, так как позволяет получать сервис в близкой к себе точке, с другой — может существенно снизить требования к полосе канала между площадками.

ADC на любой площадке может направлять запросы на обработку локальным серверам или посылать их на обработку на соседнюю, трансляция адреса потребителя делает это возможным. Для случая, когда реальные IP адреса не обязательно должны быть доступными серверам, или, когда протокол прикладного уровня допускает их передачу в заголовках, устройство территориально распределенный ЦОД мало чем отличается от того, что я назвал базис-ЦОДом. Трансляция адреса потребителя позволяет увеличивать/уменьшать количество ADC или даже перемещать экземпляры между площадками в соответствии с изменениями в матрице входящего трафика, или во время миграции/запуска. Некоторое внимание нужно уделить мониторингу объемов входящего трафика чтобы поддерживать количество ADC в рамках площадки адекватным доле трафика, которую получает площадка. Несмотря на простоту, схема вполне гибкая, обладает приятными эксплуатационными характеристиками и легко тиражируется на количество площадок большее двух.

7 image
Рис.

В требуемым момент времени, автоматически или после некоторых событий-тригеров, ADC может снять трафик с локальных серверов и переместить потребителей на соседнюю площадку. Если вы работаете с протоколом, который позволяет осуществлять пересылку запросов, как в случае HTTP Redirect, эта возможность может быть применена как дополнительный рычаг управления нагрузкой канала между площадками, как механизм проведения регламентных работ на серверах или как метод построения Active/Backup серверных ферм на разных площадках. Стоит уделить разработке этого алгоритма пристальное внимание так чтобы согласованная работа ADC исключала возможность взаимной пересылки запросов или резонанса.

В этом случае невозможно обеспечить согласованное соединение сегментов TCP сессии просто объявив в ADC default маршрут. Особый интерес представляет случай, когда серверам нужны реальные IP адреса потребителей, а протокол прикладного уровня не обладает возможностями передачи дополнительных заголовков, или, когда ADC работают без понимания семантики протокола прикладного уровня. Если вы это сделаете сервера первой площадки начнут использовать локальный ADC в качестве шлюза по умолчанию для сессий, которые пришли со второй площадки, само собой TCP сессия в этом случае не установится потому что ADC первой площадки будет видеть только одно плечо сессии.

8 image
Рис.

Хитрость заключается в том, чтобы использовать на ADC второй площадки не интерфейсные адреса серверов, а логический адрес ADC, который соответствует серверной ферме на первой площадке. Есть небольшая хитрость, которая все же позволяет запустить Active/Active ADC в сочетании с Active/Active серверными фермами на разных площадках (случай Active/Backup на двух площадках я не рассматриваю, внимательное прочтение написанного выше позволит вам решить эту задачу без дополнительного изложения). Для поддержания такого режима работы на ADC требуется активировать функцию запоминания интерфейса, с которого пришел первый пакет на установку TCP сессии. Сервера при этом принимают трафик, как если бы он пришел от локального ADC и используют локальный шлюз по умолчанию. Схема вполне работоспособная и позволяет гибко распределять нагрузку по всем доступным серверам где бы они не находились. У разных производителей эта функция называется по-разному, но суть одна и та же — запомнить интерфейс в таблице состояния сессий и использовать его для ответного трафика не обращая внимание на таблицу маршрутизации. В случае двух и более площадок выход из строя одного ADC не влияет на доступность сервиса в целом, но полностью исключает возможность обработки трафика на серверах площадки с вышедшим из строя ADC, это нужно помнить при прогнозировании поведения и нагрузки во время частичных отказов.

9 image
Рис.

Не было большой сложности просто воссоздать поведение устройств старой платформы на новой в рамках проверенной и устраивающей клиента схемы, именно этого от нас ждали.
Но посмотрите еще раз на рисунок 9, видите ли вы там то что можно оптимизировать?
Основной минус схемы работы с цепочкой ADC заключается в том, что на обработку некоторой части сессий расходуются ресурсы двух ADC. Примерно по такой схеме функционировали сервисы нашего клиента, когда я взялся за работу в проекте миграции на новую платформу ADC. В разные периоды времени двойная обработка забирала в среднем от 15-ти до 30-ти процентов ресурсов ADC, это достаточное количество чтобы подумать над оптимизацией. В случае этого клиента выбор был абсолютно осознанным, он обусловлен спецификой работы приложений и необходимостью иметь возможность очень быстро (от 20-ти до 50-ти секунд) перераспределять нагрузку между серверами разных площадок. В качестве ключа мы рассматривали такие варианты как:
Обговорив этот момент с инженерами клиента, мы предложили заменить поддержку таблицы сессий ADC с привязкой к интерфейсу на маршрутизацию по источнику на серверах с помощью PBR на IP стеке Linux.

  1. дополнительный IP адрес на серверах на общем интерфейсе для каждого ADC;
  2. интерфейсный IP адрес на серверах на отдельном 802.1q для каждого ADC;
  3. отдельная оверлей туннель сеть на серверах для каждого ADC.

Среди побочных эффектов варианта номер один нам показалось неприемлемым увеличение, кратное количеству ADC, ARP таблицы на коммутаторах, а второй вариант потребовал бы увеличения количества сквозных широковещательных доменов между площадками или отдельных экземпляров виртуальных таблиц маршрутизации. Первый и второй варианты так или иначе оказали бы влияние на сеть в целом. Локальный характер третьего варианта показался нам очень привлекательным, и мы взялись за работу, по итогу которой получился простой контроллер, который автоматизирует конфигурацию туннелей на серверах и ADC, а также конфигурацию PBR на IP стеке серверов Linux.

10 image
Рис.

Как я уже написал миграция завершилась, клиент получил то что хотел — новую платформу, простоту гибкость, масштабируемость, и, как следствие перехода на оверлей, упрощение конфигурации сетевого оборудования в рамках обслуживания этих сервисов — вместо нескольких экземпляров виртуальных таблиц и больших широковещательных доменов получилось что-то наподобие простой IP фабрики.

Некоторые ваши продукты хороши, но попробуйте обратить внимание на более тесную интеграцию с приложениями на серверах, автоматизацию их настроек и оркестрацию всего процесса разработки и эксплуатации. Коллеги, которые работают у производителей ADC, этот абзац посвящен в большей степени вам. Мне это представляется в виде классического взаимодействия контроллер-агента, внося изменения на ADC пользователь инициирует обращение контроллера к зарегистрированным агентам, это то что сделали мы с клиентом, но «из коробки».

Возможности приложений на серверах очень широки, поэтому иногда проще организовать серьезную application specific проверку работы сервиса на самом агенте. Помимо этого, некоторым клиентам покажется удобной переход с PULL модели взаимодействия с серверами на PUSH модель. Сервисы, в которых участвует сервер, можно передавать напрямую от агента к ADC в виде чем-то похожем на расширенный BGP Flow-Spec. Если проверка дает положительный результат агент передает информацию, например, в виде похожем на BGP Cost Community, для использования в алгоритмах взвешенного расчета весов.
Зачастую обслуживание серверов и ADC выполняют разные подразделения организации, переход на PUSH модель взаимодействия мог бы быть интересен тем что эта модель избавляет от необходимости координации между подразделениями по интерфейсу человек-человек.

К чему я все это… Находясь в свободном выборе мы принимаем решении в пользу более удобного, более подходящего или в пользу варианта, который расширяет окно возможностей чтобы минимизировать свои риски. Много чего еще можно написать. Многие производители балансировщиков нагрузки отмечают снижение востребованности своих продуктов. Крупные игроки интернет индустрии для решения своих задач изобретают что-то совсем инновационное, то что диктует завтрашний день, игроки поменьше и компании с опытом разработки программного обеспечения все чаще применяют такие технологии и продукты, которые допускают глубокую кастомизацию под себя. Балансировщики пока стоят на пороге, сделайте этот шаг пока дверь открыта, в противном случае вы рискуете потерять конкурентные преимущества и переместиться на периферию. Иными словами, сервера и приложения, которые на них работают, коммутаторы и маршрутизаторы некоторое время назад уже качественно изменились и вошли в SDN эру.


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

[recovery mode] .NET гуру Дино Эспозито: «Не будь пассажиром поезда, идущего под откос»

Дино приезжал в Минск лишь однажды, и нам удалось пообщаться с ним между лекциями, которые он давал для .Net-чиков. Мы решили не быть банальными и поговорили с Дино не только о работе, но и о книгах, о будущем и о ...

Рассылай и властвуй: инструменты для создания и тестирования рассылки

Верстать и тестировать адаптивные письма с интерактивом (например, с формами и слайдерами) — боль в квадрате. Верстать электронные письма — это боль. В статье расскажу об email-фреймворках — MJML и Foundation for Emails — и моих любимых ресурсах для тестирования ...