Data Center TCP (DCTCP) в Windows Server 2012 R2

DCTCP и управление TCP с использованием ECN - новый функционал Windows Server

Привет.

Сети датацентров – пожалуй, одно из самых высокотехнологичных и передовых мест в современных сетевых технологиях, которое вдобавок находится на стыке массы технологий. Задача вида “выжать максимум” здесь является не уникальной, а операционной, поэтому надо быть во всеоружии. Давайте поговорим про то, кто такой новый TCP – DCTCP и чем он нам поможет.

Я предполагаю, что читатель знаком с сетевыми технологиями хотя бы на уровне базового бесплатного курса Cisco ICND1 3.0. Если нет – не страшно, но для полного понимания логики происходящего всё ж лучше представлять, как работает TCP и его отдельные подсистемы.

DCTCP в Windows Server 2012 R2

  • Проблемы протокола TCP
  • TCP Flow Control
  • TCP Global Syncronization
  • Управление заторами – ECN
  • Включение поддержки ECN и DCTCP
  • Настройка профилей TCP / DCTCP в Windows Server 2012 R2

Начнём.

Проблемы протокола TCP

Протокол TCP – очень хороший протокол. Количество решаемых им задач и имеющегося функционала – очень велико. И потоком он управлять умеет, и sequencing делает, и полнодуплексно работает, и разные логики изменения размера окна знает, и всякие out-of-band данные отправлять умеет. Но есть минус. В протоколе TCP нет поддержки телепатии.

Казалось бы – при чём здесь, при обсуждении транспортного протокола, телепатия? А дело в том, что если бы TCP мог телепатически изучать конфигурацию всех сетевых устройств, включая L2-коммутаторы, которые расположены по трассе путешествия TCP-сегментов, жить ему было бы гораздо лучше. Рамочная суть проблемы TCP, связанной с заторами, формулируется так – протокол TCP при работе не понимает причину задержки/потери сегментов и пытается решить этот вопрос, играя размером окна. Он не знает, как именно идёт буферизация, чей и какой буфер перегружен, и не умеет понимать разницу между, допустим, приёмом данных во входящую очередь на порту и приёмом данных в буфер со стороны получателя.

Сразу оговорюсь, что вопросы тюнинга TCP и его функционала – штука крайне обширная, и в данной статье нет задачи охватить их все. Для хорошего изучения TCP нужен фундаментальный подход – при нескольких десятках модифицируемых параметров другие подходы смысла не имеют, нужно понимать суть, вариант “данный параметр лучше в такое значение, чем такое, просто потому что лучше” не подойдёт. Здесь же мы говорим про DCTCP.

Представьте себе для наглядности аналогичную ситуацию с другой подсистемой. Есть программный RAID, который получает запрос на запись большого количества данных. RAID радуется, распределяет их по дискам (например, это обычный stripe на пару дисков), и начинает передавать. У каждого диска – кэш, допустим 64МБ. Диски очень бодро кушают данные, RAID радуется, и выдаёт прогноз по скорости записи – мол, с такой-то скоростью мы сейчас всё очень быстро сделаем. Но после передачи около 128МБ диски неожиданно говорят – “Стоп, технический перерыв – нам надо теперь это по факту записать на блины”. RAID пугается и прогноз резко изменяется – теперь оказывается, что диски, быстро употребляющие данные, на самом деле гораздо медленнее, чем ожидалось. В зависимости от реализации RAID, работы ОС с этим RAID и работы приложения с API этой ОС могут быть разные ситуации – но суть будет в том, что данные могут начать сбрасываться “волнами”, что далеко по эффективности от возможной максимальной скорости записи на массив.

Как же выглядит работа обычного TCP в подобной ситуации?

TCP Flow Control

Стандартно в протоколе TCP реализован механизм управления потоком данных (не путать с 802.3x Flow Control, который реализован на уровне порта Ethernet), когда одна сторона может сказать другой “Притормози, а то ты много данных уже накидала через данную сессию конкретному приложению, оно не успевает разгружать буфер, если будешь присылать ещё, то придётся выбрасывать”. Данная ситуация может возникнуть по многим причинам – например, отправляющий хост может передавать быстро, а принимающий хост сильно загружен в плане процессора и то приложение, которому принадлежит принимающий порт, не успевает обрабатывать данные. Размер буфера обычно указывается при регистрации TCP-порта через интерфейс Winsock, а логика отправки уведомления “not ready” также может быть различной. Говоря проще, Вы можете влиять на то, при каком проценте заполненности буфера надо уведомлять противоположную сторону, что больше отправлять не надо – делать это при 100% загрузки уже поздно, ведь пока уведомление будет идти по сети, к Вам могут доехать дополнительные tcp-сегменты, которые уже будет некуда сохранять.

Но опять же, это не единственная проблема – плюс, данная логика отталкивается исключительно от степени заполнения буфера приёма. А с ним могут быть и другие проблемы.

TCP Global Syncronization

Глобальная синхронизация – нехороший артефакт TCP Flow Control. Суть его в том, что если у хоста много TCP-сессий, и все они управляются идентичной логикой, то возникают “waves of congestion”. Т.е. допустим, у Вас есть веб-сервер. Он честно, включаясь, застолбил за собой 80й TCP-порт, Winsock выделил буфер для приёма и началась работа. Клиенты начали подключаться и работать. Активно работать – например, постить комментарии в форум. Буфер приёма наполняется, приложение активно разбирает из него данные, но вот наполнение буфера переходит критическую границу, и Winsock немедленно рассылает всем уведомление “За мной не занимать, притормозите”. Okay – говорят все, и перестают постить огромные картинки. Приложение активно разбирает буфер, и, когда дело доходит до другого барьерного числа – “буфер разгружен” – стек Winsock рассылает всем сообщение – “продолжаем”. Все радостно и синхронно кидают висящие у них в буферах отправки данные, и буфер приёма разово перехлёстывает волной трафика так, что происходит tail-drop. Ситуация с криком “За мной не занимать” повторяется, только уже хуже – ещё и часть данных потеряли. Уведомление о том, что принята только часть (selective ack) отправляются – с отправкой-то всё ОК, поэтому отправители знают, что данные потеряны, и готовятся передать их повторно. Но, как понятно, при следующем сигнале “продолжаем” ситуация повторяется – опять разовая приливная волна, опять буфер затопило, опять часть данных потеряли, опять общий крик “притормозили”, и снова, снова.

Данная ситуация может быть и на уровне порта маршрутизатора, в который входит много данных, которые, допустим, массово хотят выйти через менее скоростной порт, ну или у маршрутизатора небыстрая обработка оных – опять будет ситуация вида “20 tcp-сессий равномерно передают данные, буфер кончился, у все разово по чуть-чуть потеряли сегменты, все разово в силу sliding windows схлопнули окно передачи, затаились (slow start), а потом разово выбросили пачки сегментов, и опять на том же порту разово перегрузился буфер”.

Что же со всем этим делать? Конечно, есть “лобовые” методы – например линейно увеличивать размеры буферов, скорость каналов, но это всё, в общем-то не панацея, притом совсем. Сетевик, который придёт к фин.ответственному лицу и скажет “у нас тут в общем канал 100Мбит наружу, там иногда пакеты пропадают, давайте гиг купим”, получит именно то, что заслуживает – трудовую.

Это не наш вариант. Что же привнесёт нового в TCP протокол DCTCP?

Управление заторами – ECN и ECN+

Explicit Congestion Notification – дополнение к протоколам IP и TCP, которое должно поддерживаться не только конечными участниками TCP-сессии, но и промежуточными узлами (привет покупателям “простой свичик главное чтобы гигабитный остальное ненужные навороты”). Суть его (ECN) работы достаточно проста, и разбивается на две части – работа с IP и работа с TCP.

ECN и IP

В IP ECN использует зарезервированные биты в ToS-поле заголовка, чтобы информировать про факт затора в сети. Эти биты – два оставшихся после DSCP-маркинга бита в ToS, никем до ECN особо не использовавшиеся. Если оба этих бита нули, то ECN не поддеживается (это называется Non-ECT – Non ECN Capable Transport). Если узел поддерживает ECN – он ставит 10, это обозначает ECN Capable Transport. Если произошёл затор – в эти биты ставится обе единицы. Это важный момент с точки зрения скорости, т.е. сетевое оборудование не нуждается в глубоком парсинге TCP-заголовков и отслеживанию session state, чтобы определить факт затора.

ECN и TCP

Поддержка ECN согласовывается в TCP на момент установки сессии. Если согласовалась – во всех IP-пакетах, в которые помещаются TCP-сегментых с данными, будет установлен признак ECT. Кстати, если поддерживается ECN+, то метиться на L3 будут ещё и служебные сегменты (ACK и SYN), что усиливает положительный эффект от ECN.

Полезная штука? Безусловно. Давайте сразу включим её.

Включение поддержки ECN и DCTCP

Сколько не видел материалов от Крутых Ситивиков из Microsoft, все поголовно тупо копипастили маркетинговую презентацию, где “Всё-это-само-работает-ничего-не-надо-настраивать”. Это не так.

Выполним под админскими правами данный командлет:

Set-NetTCPSetting -ECNCapability Enabled

Теперь DCTCP.

Set-NetTCPSetting -CongestionProvider DCTCP

Скорее всего, будет заметна ругань системы на то, что модифицировать можно только custom templates – а это значит, что нам надо будет углубляться в настройки. Ранее, в Windows Server 2012, был доступен для редактирования только template с названием Custom – теперь, в Windows Server 2012 R2 доступны InternetCustom и DatacenterCustom. В хелпе на сайте Microsoft пока что старая версия, не обращайте на неё внимание – шаблона Custom теперь просто нет. Поправим наши команды в соответствии со спецификой новой серверной ОС:

Set-NetTCPSetting -SettingName DatacenterCustom -ECNCapability Enabled -CongestionProvider DCTCP

База сделана, теперь конкретика – нам надо явно указать, что мы хотим для определённого трафика именно использования Datacenter-настроек.

Настройка профилей TCP / DCTCP в Windows Server 2012 R2

Профили TCP – это готовые пачки настроек системы для разных сценариев. Можно навскидку придумать как минимум три сценария – “для датацентров, где быстрая локальная сеть и мощные высоконагруженные хосты”, “для Интернета, где от меня до целевого узла куча сегментов и оборудования с разной пропускной способностью, MTU, загрузкой и размерами буферов”, и “универсальный с усреднёнными настройками”. Примерно так в Windows Server 2012 R2 и сделано – можете убедиться:

Get-NetTCPSetting

Какие подключения будут использовать какой из профилей? Это тоже можно посмотреть:

Get-NetTCPConnections

В правой колонке, где AppliedSetting, будет видно название профиля – заметим, что только для тех подключений, которые установлены и работают – для открытых портов (которые Listen), или TCP-сессий, находящихся в TimeWait, профиль не применяется, что и логично. Вывести все подключения, использующие конкретный профиль, тоже несложно:

Get-NetTCPConnections -AppliedSetting Internet

Ну а теперь создадим транспортный фильтр, который явно укажет, какой трафик должен использовать наш шаблон DatacenterCustom:

New-NetTransportFilter –SettingName DatacenterCustom –DestinationPrefix 172.16.0.0/16

Вы можете также задать условия в части портов отправителя/получателя, используя параметры -RemotePortStart и -RemotePortEnd, и -LocalPortStart и -LocalPortEnd. Параметра, задающего source prefix, нет, да он и не нужен – эта политика работает исходя из того, что под неё подпадают все TCP-сессии с локального хоста. Кстати, там есть ещё параметр -Protocol, намекающий, что возможно, это когда-нибудь будет работать и не только для TCP (технически это возможно), но пока декоративный.

В общем всё. Шаблон действует сразу, доп.команды по включению не нужны.

Используйте данную полезную технологию – преимуществ DCTCP много, это и экономия места для буферизации данных TCP, и уменьшение потерь пакетов, и ощутимо более шустрая работа при сценариях “получатель загружен несколькими потоками данных с разной интенсивностью”. Желающие почитать подробнее могут зайти вот по этой ссылке – http://simula.stanford.edu/~alizade/Site/DCTCP_files/dctcp_analysis-full.pdf и узнать полезные детали.

Удач в применении!

Возможно, вам будет также интересно почитать эти статьи с нашей Knowledge Base

Ruslan V. Karmanov

Зайдите на сайт под своей учётной записью, чтобы видеть комментарии под техническими статьями. Если учётной записи ещё нет - зарегистрируйтесь, это бесплатно.