Lossless Ethernet или жизнь без потерь: PFC, буферы и тонкая настройка

Привет, меня зовут Александр Шереметьев, я старший инженер по разработке ПО для коммутатора KORNFELD в YADRO. Мы привыкли, что Ethernet — среда с доставкой по мере возможности. Если возник затор, пакет дропается, а Transmission Control Protocol потом разбирается сам. Но сегодня мы строим сети для AI-кластеров и распределенных систем хранения, где задержка в несколько миллисекунд на ретрансмит пакета — это катастрофа, которая просаживает производительность всей системы на 30–40%.
Сегодня мы разберем, как прокачать Ethernet до уровня Lossless, чтобы по надежности он не уступал Fibre Channel, но оставался гибким и быстрым. Мы залезем под капот коммутатора и посмотрим, как математически рассчитываются буферы и почему настройка одной лишь технологии PFC — это только верхушка айсберга.
Почему классический Ethernet не тянет?
TCP (Transmission Control Protocol) справляется с потерями через ретрансмиты, но это вызывает лавинообразный рост задержек и падение пропускной способности. К тому же появляются новые игроки RoCE v2 (RDMA over Converged Ethernet), NVMe-oF, AI Training (GPU-to-GPU) и диктуют требование: Zero Packet Loss. Если упадет хоть один пакет в RDMA-сессии, вся передача встает на паузу, пока работает механизм Go-Back-N. Какое решение мы можем предложить? Data Center Bridging (DCB) — набор стандартов для превращения Ethernet в надежную транспортную среду.
Оставить все как есть не можем, потому что есть проблема в протоколах RDMA (RoCE v2), которые сейчас используют все — от NVIDIA до Microsoft. В отличие от TCP, RDMA не умеет эффективно справляться с потерями. При потере одного пакета срабатывает механизм Go-Back-N: передатчик должен переотправить все, что было послано после потерянного пакета.
В сетях 100G, 400G и 800G это вызывает эффект Incast, когда множество отправителей забивают буфер одного порта. Если мы допустим потерю пакета, вся вычислительная мощь GPU будет простаивать, ожидая пересылки данных. Наша задача — создать затор без потерь: остановить отправителя до того, как буфер переполнится.
Простыми словами, Go-Back-N — стратегия переотправки данных в протоколах передачи, когда при потере одного пакета отправитель вынужден «вернуться назад» и заново отправить вообще все, что было послано после этого пакета.
В контексте нашего разговора про Lossless Ethernet это критически важно, потому что именно так работает RoCE v2 (RDMA over Converged Ethernet) на аппаратном уровне сетевых карт.
Как это работает
Представим, что мы отправляем другу пронумерованные коробки: 1, 2, 3, 4, 5.
Мы отправили все пять коробок одну за другой, не дожидаясь подтверждения (это называется «окно передачи»).
Друг получил коробку №1. Все хорошо.
Коробка №2 потерялась (дроп на коммутаторе).
Друг получает коробку №3. Но по логике Go-Back-N он обязан ее выбросить, потому что она пришла не по порядку. Он ждет №2.
Коробки №4 и №5 он тоже выбрасывает в мусор, даже если они доехали в идеальном состоянии.
Мы как отправитель понимаем, что подтверждения на коробку №2 нет.
Мы возвращаемся к N (где N — это №2) и заново отправляем 2, 3, 4 и 5.
Это важно, потому что в современных высокоскоростных сетях (100G/400G) количество данных, которые мы успеваем выплюнуть в кабель до получения подтверждения, может быть огромным. Последствия печальные:
Мы тратим ресурсы на переотправку данных, которые на самом деле уже успешно долетели до получателя, но были им отброшены из-за логики протокола.
Пока идет переотправка, полезная работа задерживается.
Если сеть уже перегружена, повторная отправка целой пачки пакетов создает еще большую нагрузку, вызывая новые дропы.
Хотите работать со сложными системами в направлении Enterprise в YADRO? Откликайтесь на вакансию старшего инженера. На позиции оценят уверенное владение Linux и знание Go.
Почему TCP умнее, а RDMA — нет?
Но ведь в обычном интернете пакеты иногда теряются, и все не так плохо? Да, современный TCP умеет говорить: «Я получил 1, 3, 4 и 5. Пришли мне только номер 2». Это называется выборочным подтверждением. Работает эффективно, но требует много памяти и мощного процессора для обработки очереди на стороне получателя.
Тем временем, чтобы добиться сверхнизких задержек, логика RDMA / RoCE v2 зашита прямо в железо сетевой карты (ASIC NIC). Чтобы сделать чип дешевым, простым и быстрым, разработчики выбрали максимально простую логику: Go-Back-N. Она не требует сложного управления памятью на сетевой карте.
Мы не можем позволить себе дропнуть даже один пакет RoCE. Из-за механизма Go-Back-N потеря одного пакета весом 1500 байт превращается в переотправку сотен килобайт трафика. Сеть начинает «заикаться», и наши GPU-кластеры вместо вычислений просто ждут, пока сетевые карты обработают старые данные.
Priority-based Flow Control — это база
Обычный Flow Control (802.3x) работает слишком грубо. Он останавливает весь трафик на линке. Но в дата-центре нам нужно, чтобы SSH и BGP продолжали работать, даже если трафик хранилища встал на паузу.
PFC (802.1Qbb) работает точечно. В системе предусмотрено 8 приоритетов. Например, третий приоритет может быть выделен под RoCE-трафик. Технология PFC применяется к unicast-трафику, поэтому коммутатор обрабатывает его в unicast-очереди на выходном порту.
Когда буфер очереди соответствующего приоритета переполняется, коммутатор отправляет соседнему коммутатору кадр PAUSE, содержащий номер приоритета и время, на которое необходимо приостановить передачу. Получив этот кадр, соседний коммутатор приостанавливает передачу трафика из очереди с указанным приоритетом, например, приоритетом 3. Остальные очереди продолжают передачу трафика независимо от состояния данной очереди.
Из чего состоит буфер коммутатора
Буфер в современном ASIC — самый дорогой ресурс. Из чего он складывается:
Ingress Admission Control — проверка, есть ли место, когда пакет входит в порт.
Shared Pool — разделяемый объем памяти, который динамически или статически, в зависимости от настройки, делится между физическими портами.
Reserved (Dedicated) Buffer — гарантированный минимум для каждого порта или очереди, чтобы избежать голодания.
Чтобы настроить Lossless, нужно понимать, как коммутатор распоряжается памятью. Память в современных чипах — дефицитный ресурс. Она делится на пулы, каждый пул имеет полный объем памяти, из которого выделяется буфер запаса.
Для каждого порта создается профиль. Профили используют ресурсы пула.
Профиль может быть статическим и динамическим. Эта настройка определяет, как будет выделяться память из пула для конкретного порта. Если профиль динамический, то настройка размера буфера определяется в процентах, если статическая, то в байтах. Другие настройки профиля включают зарезервированный размер, для входящего профиля — пороги XOFF, XON, XON-OFFSET.
Об этом поговорим дальше.
Что такое Headroom: «тормозной путь» пакета
Headroom — зарезервированная часть буфера для поглощения транзитных пакетов после отправки сигнала XOFF. Концепция важна, когда заполнение буфера достигает порога, коммутатор отправляет сигнал PAUSE, а пакеты все еще продолжают лететь по кабелю.
Из чего складывается Headroom:
скорость порта (чем выше скорость, тем больше нужно буфера)
время полета сигнала по оптике (туда и обратно).
время на генерацию и обработку кадра PAUSE.
размер полезной нагрузки.
различные заголовки.
Если Headroom слишком мал, пакеты дропнутся. Если слишком велик, мы потратим память впустую. Это важный момент. Представьте: буфер порта заполнился до критической отметки, и коммутатор отправил сигнал PAUSE. Но пакеты не остановятся мгновенно. Те пакеты, что уже находятся «в проводе» и те, что передатчик успел вытолкнуть до получения команды PAUSE, все равно долетят до нас.
Headroom как раз таки поглощает транзитные пакеты. Если неверно рассчитать Headroom для длинного кабеля, то пакеты просто отбросятся, и ваш Lossless Ethernet превратится в потерю потерь.
Управление буфером: пороги XOFF и XON
Управление буфером строится на превышении порогов:
XOFF Threshold — уровень заполнения буфера для входящих приоритетов, при достижении которого порт отправляет PAUSE соседнему устройству.
XON Threshold (Xon + xon-offset) — уровень, до которого должен опустеть буфер, чтобы порт отправил сигнал «продолжай передачу».
Hysteresis — разница между XOFF и XON, чтобы избежать дребезга (частой отправки мелких пауз).
XOFF Threshold — это верхний порог. Как только уровень данных во входящем приоритете достигает его, генерируется PFC PAUSE.
XON Threshold — нижний порог. Мы не разрешаем передачу сразу, как только освободился один байт. Мы ждем, пока буфер опустеет до уровня XON, чтобы избежать частого прерывания, остановки трафика и постоянной отправки мелких пауз, которые «рвут» трафик. Разница между ними называется гистерезисом. В высокопроизводительных сетях мы стараемся держать эти значения максимально близко, но без ущерба стабильности. Мы используем два порога xon и xon-offset. Какой достигается раньше, тот и срабатывает для отмены паузы.
В чем проблема обычного XON?
В классической схеме мы задаем статический порог XON. Например, «возобнови работу, когда в очереди останется 100 КБ». Но в современных коммутаторах буфер — это динамический общий ресурс. Размер доступной памяти постоянно меняется. Если общая нагрузка на коммутатор очень высокая, свободная память в пуле может закончиться глобально.
Риск «липкой паузы» (Sticky Pause)
Если используем статический XON, может возникнуть ситуация, когда очередь порта немного освободилась. Но из-за того, что общий буфер чипа переполнен другими портами, уровень заполнения очереди никогда не опустится до статического порога XON. Порт «зависнет» в состоянии паузы навсегда, хотя он готов принимать данные. Это одна из причин PFC Deadlock, когда вся сеть ждет друг друга и трафик не передается по нужному приоритету.
Что такое XON-OFFSET?
Порог XOFF может быть настроен как статически, так и динамически. В наших реализациях используется динамическое управление порогом. Поэтому для определения момента возобновления приёма трафика используется комбинация двух параметров — XON и XON-OFFSET. Такой подход снижает вероятность переполнения буфера и позволяет использовать два условия для выхода из состояния паузы.
XON-OFFSET — это относительная величина, которая определяет порог возобновления передачи (XON) относительно порога остановки (XOFF).
XON = XOFF - XON_OFFSET
Вместо того чтобы ждать, пока буфер опустеет до какой-то абсолютной отметки (например, 100 КБ), мы говорим коммутатору: «Как только порт освободит N килобайт после отправки команды PAUSE, сразу отправляй XON».
Главные преимущества:
Гарантированный выход из паузы. Поскольку XON привязан к XOFF, мы гарантируем, что как только порт вытолкнул из себя объем данных, равный OFFSET, он отправит сигнал возобновления. Нам неважно, сколько памяти осталось в общем пуле чипа. Мы смотрим только на дельту (изменение) внутри конкретной очереди.
Минимизация джиттера. Маленький OFFSET позволяет порту очень быстро «включаться» обратно. Это делает поток данных более плавным.
Защита от Shared Pool Starvation. Даже если другие порты «съели» весь общий буфер, наш порт сможет продолжать работу короткими итерациями, потому что его порог XON всегда достижим.
То же самое и в обратной ситуации, при практически полной заполняемости буфера может оказаться, что XON_OFFSET ниже XON. Тогда выйти из ситуации Shared Pool Starvation поможет xon. Поэтому отправка сигнала «возобнови работу» происходит при достижении любого из порогов. Все зависит от настройки буферов памяти для конкретного приоритета.
Priority Groups: логика обслуживания
На входном порту трафик попадает в Priority Groups. Это логические контейнеры. Мы должны четко разделить: PG0 — для обычного трафика, где нет Headroom и возможны дропы. Например, PG3 — для Lossless-трафика. Важно строго соблюдать маппинг: PCP/DSCP -> TC -> PG -> Queue. Ошибка на любом этапе ломает lossless-цепочку.
Есть нюанс: если вы на входе пометили трафик как Lossless, вы обязаны пронести эту информацию через всю вашу сеть. Если на каком-то промежуточном коммутаторе маппинг настроен неверно, трафик попадет в общую очередь без PFC-защиты, и вы получите непредсказуемые потери, которые будет крайне сложно отладить.
Тонкая настройка
В настройках современных коммутаторах есть параметр Alpha. Это коэффициент, который определяет агрессивное использования Shared Pool.
Большая
Alpha— порт может агрессивно забирать память.Малая
Alpha— изоляция портов выше, но общая утилизация буфера хуже.
Формула проста: Free_Space * Alpha / (1 + Alpha). Если Alpha большая, например 8, порт может занять почти весь буфер. Это хорошо для коротких всплесков, но плохо для честного распределения ресурсов.
В таблице показан процент от свободного места в разделяемом буфере, который может занять группа приоритетов:
Процент | Alpha |
0.78% | 1/128 |
1.5% | 1/ 64 |
3% | 1/32 |
6% | 1/16 |
11% | 1/8 |
20% | 1/4 |
33% | 1/2 |
50% | 1 |
66% | 2 |
80% | 4 |
89% | 8 |
Для Lossless-очередей мы часто используем статические лимиты или очень консервативные значения Alpha, чтобы гарантировать, что грязный трафик из соседней очереди не съест буфер, предназначенный для RDMA
Лучшие практики от KORNFELD
Техническое задание
Настроить коммутатор D1156 для поддержки Lossless так, чтобы разделяемый буфер коммутатора был максимальным, что позволит сглаживать трафик на всех портах.
В порты Ethernet 1–5 подключатся сервера, требующие передачу трафика без потерь.
Сервера используют сетевые карты со скоростью 25 Гбит/с.
В качестве аплинков используются порт Ethernet 48–49 объединенные в агрегацию.
Длина кабелей до серверов 10 метров, аплинки 100 метров.
Для передачи lossless трафика используется приоритет 3.
Использовать оптимальные настройки профилей для используемых портов.
Остальные порты и приоритеты используются только для lossy трафика.
Расчет производить для RoCEv2 с размером полезной нагрузки 1024 байта.
Порты к серверам и аплинки используются в режиме транк (
dot1q).
Решение
Для начала рассчитаем параметры буфера запаса Headroom для пула.
Для этого надо рассчитать параметры xoff для порта к серверу и для аплинка, в данном случае это размер буфера запаса для профиля, используемого группой приоритетов.
Используя методику, рассчитаем xoff для порта 25 Гбит/с, длины кабеля 10 метров.
latency = 1000 нс
delay_{media} = 100 нс
length_{cable} = 10 метров
cell size = 256 байт на коммутаторе Broadcom Trident 3
М = 64 для Broadcom коммутатора
delay_{propagation} = 5 нс на 1 метрРасчет количества ячеек, которое требуется для хранения одного пакета полезной нагрузки RoCEv2.
size_{packet} = BTH + RoCEv2-PAYLOAD + ICRC = 12 + 1024 + 4 = 1040
PacketToCells=ceiling[(size_{packet} + M) / size_{cell}] = ceiling((1040 + 64) / 256) = 5Расчет времени, которое пройдет между моментом превышением порога xoff профиля и остановкой отправки трафика.
t = 2*(latency + delay_{media} + length_{cable}*delay_{propagation}) = 2 (1000 + 100 + 10 5) = 2300 нсУмножение на 2 требуется, так как пакет проходит сериализацию дважды: один раз на отправляющей стороне, второй – на принимающей.
После превышения порога xoff пакет паузы проходит через кабель от приемника трафика до передатчика, а после остановки передачи, отправленные пакеты проходят через кабель от передатчика до приемника.
Расчитаем pps:
L3PACKET состоит из IPv4-L3-HEADER = 20 байт, UDP-HEADER = 8 байт и полезной нагрузки size_{packet} = 1040.
FRAMESIZE_{L1} = Preamble + SFD + L2-HEADER + VLAN-TAG + L3PACKET + FCS + IGP = 7 + 1 + 14 + 4 + 20 + 8 + 1040 + 4 + 12 = 1110 байтpps = IntfSpeed / FRAMESIZE_{L1} = 25000000000 / (1110 * 8) = 2815315Расчет количества пакетов, которые будут переданы за время t:
PacketsInline = ceiling(t / 10^{9} pps) = ceiling(2300 / 10^{9} 2815315) = 7 пакетовИтог: XOFF25G_{server} = PacketsInline PacketToCells size_{cell} = 7 5 256 = 8960 байт
Проделаем тот же расчет для порта 100Гбит/с и длины кабеля 100 метров.
XOFF100G_{uplink} = 47360 байт.Размер Headroom пула будет суммой используемых XOFF-профилей.
HEADROOM_{pool} = NumberOfServerPorts XOFF25G_{server} + NumberOfUPlinkPorts
XOFF100G_{uplink} = 5 8960 + 2 47360 = 139520Расчет завершен, переходим к настройке. Порты к серверам и аплинки уже настроены, настраиваем только буферы. Определим текущий пресет:
kornfeld# show qos buffer preset
Current presets: defaultНастройки буферов возможно только при использовании пресета custom, текущий пресет default. Требуется перевести коммутатор в пресет custom.
kornfeld# configure terminal
kornfeld(config)# qos buffer preset custom
%Warning: Traffic will be stopped before ending process!
kornfeld(config)# exit
kornfeld# show qos buffer preset
Current presets: custom
kornfeld#Создаются пулы и профили, профили привязываются к группам приоритетов и очередям:
kornfeld# show running-configuration qos buffer
!
qos buffer preset custom
!
qos buffer pool egress_lossless_pool
size 16777216
!
qos buffer pool egress_lossy_pool
size 15409152
!
qos buffer pool ingress_lossless_pool
size 16777216
Headroom 9863168
!
qos buffer pool ingress_lossy_pool
size 15788800
!
qos buffer profile egress_lossless_profile pool egress_lossless_pool type dynamic
shared-size 66
!
qos buffer profile ingress_lossless_profile pool ingress_lossless_pool type dynamic
shared-size 33
xoff 88064
xon 9472
xon-offset 25600
kornfeld# show qos buffer interface Ethernet 1 priority-group
Ethernet1
---------------------------------------
Priority-group Profile
---------------- ---------------------
0 ingress_lossy_profile
1 ingress_lossy_profile
2 ingress_lossy_profile
3 ingress_lossy_profile
4 ingress_lossy_profile
5 ingress_lossy_profile
6 ingress_lossy_profile
7 ingress_lossy_profile
kornfeld# show qos buffer interface Ethernet 1 unicast-queue
Ethernet1
-----------------------------
Queue Profile
------- --------------------
UC0 egress_lossy_profile
UC1 egress_lossy_profile
UC2 egress_lossy_profile
UC3 egress_lossy_profile
UC4 egress_lossy_profile
UC5 egress_lossy_profile
UC6 egress_lossy_profile
UC7 egress_lossy_profile
kornfeld#Изменим пул, предназначенный для lossless. Настроим Headroom согласно расчету.
kornfeld# show qos buffer pool
----------------------------------------------------------------
Pool Type Size (Byte) Headroom (Byte)
--------------------- ------- ------------- -----------------
egress_lossless_pool egress 16777216 0
egress_lossy_pool egress 15409152 0
ingress_lossless_pool ingress 16777216 9863168
ingress_lossy_pool ingress 15788800 0
kornfeld# configure terminal
kornfeld(config)# qos buffer pool ingress_lossless_pool
kornfeld(config-pool)# Headroom 139520
kornfeld(config-pool)# show configuration
!
qos buffer pool ingress_lossless_pool
size 16777216
Headroom 139520
kornfeld(config-pool)# exit
kornfeld(config)# exit
kornfeld# show qos buffer pool
----------------------------------------------------------------
Pool Type Size (Byte) Headroom (Byte)
--------------------- ------- ------------- -----------------
egress_lossless_pool egress 16777216 0
egress_lossy_pool egress 15409152 0
ingress_lossless_pool ingress 16777216 139520
ingress_lossy_pool ingress 15788800 0
kornfeld#Пул изменился. Создадим профиль для входящего трафика для портов к серверам. Как пример, будем использовать предустановленный профиль ingress_lossless_profile.
Тип пула dynamic, XON и XON-OFFSET оставим рекомендованные производителем:
kornfeld# show qos buffer profile ingress_lossless_profile
--------------------------------------------------------------------------------------------------------------------------------------------------------------
Profile Pool Reserved Size(Byte) Shared Mode Shared Size(Byte or %) Xoff(Byte) Xon(Byte) Xon-offset(Byte)
------------------------ --------------------- --------------------- ------------- ------------------------ ------------ ----------- ------------------
ingress_lossless_profile ingress_lossless_pool 0 dynamic 33% 88064 9472 25600
kornfeld#
kornfeld# configure terminal
kornfeld(config)# qos buffer profile SERVERS-profile pool ingress_lossless_pool type dynamic
kornfeld(config-profile)#У созданного профиля выставлены настройки по умолчанию, но они не подходят для реализации технического задания:
kornfeld(config-profile)# do show qos buffer profile SERVERS-profile
-----------------------------------------------------------------------------------------------------------------------------------------------------
Profile Pool Reserved Size(Byte) Shared Mode Shared Size(Byte or %) Xoff(Byte) Xon(Byte) Xon-offset(Byte)
--------------- --------------------- --------------------- ------------- ------------------------ ------------ ----------- ------------------
SERVERS-profile ingress_lossless_pool 0 dynamic 66% 0 0 0
kornfeld(config-profile)#Изменим настройки профиля и проверим параметры созданного профиля:
kornfeld(config)# qos buffer profile SERVERS-profile pool ingress_lossless_pool type dynamic
kornfeld(config-profile)# shared-size 33
kornfeld(config-profile)# xon 9472
kornfeld(config-profile)# xon-offset 25600
kornfeld(config-profile)# xoff 8960
kornfeld(config-profile)# show configuration
!
qos buffer profile SERVERS-profile pool ingress_lossless_pool type dynamic
shared-size 33
xoff 8960
xon 9472
xon-offset 25600
kornfeld(config-profile)# exit
kornfeld(config)# exit
kornfeld# show qos buffer profile SERVERS-profile
-----------------------------------------------------------------------------------------------------------------------------------------------------
Profile Pool Reserved Size(Byte) Shared Mode Shared Size(Byte or %) Xoff(Byte) Xon(Byte) Xon-offset(Byte)
--------------- --------------------- --------------------- ------------- ------------------------ ------------ ----------- ------------------
SERVERS-profile ingress_lossless_pool 0 dynamic 33% 8960 9472 25600
kornfeld#По аналогии, создадим профиль для входящего трафика для портов аплинков:
kornfeld(config)# qos buffer profile UPLINK-profile pool ingress_lossless_pool type dynamic
kornfeld(config-profile)# shared-size 33
kornfeld(config-profile)# xoff 47360
kornfeld(config-profile)# xon 9472
kornfeld(config-profile)# xon-offset 25600
kornfeld(config-profile)# show configuration
!
qos buffer profile UPLINK-profile pool ingress_lossless_pool type dynamic
shared-size 33
xoff 47360
xon 9472
xon-offset 25600
kornfeld(config-profile)# show qos buffer profile UPLINK-profile
----------------------------------------------------------------------------------------------------------------------------------------------------
Profile Pool Reserved Size(Byte) Shared Mode Shared Size(Byte or %) Xoff(Byte) Xon(Byte) Xon-offset(Byte)
-------------- --------------------- --------------------- ------------- ------------------------ ------------ ----------- ------------------
UPLINK-profile ingress_lossless_pool 0 dynamic 33% 47360 9472 25600
kornfeld(config-profile)#Также по рекомендации для KornfeldOS 1.9.0 требуется настроить входящий пул и входящий профиль для lossy-трафика согласно документации и привязать этот профиль на все группы приоритетов для lossy. По нашему техническому заданию это 0–2, 4–7, так как третий приоритет для lossless.
Настроим пул:
kornfeld(config)# qos buffer pool ingress_lossy_pool
kornfeld(config-pool)# size 32566016
kornfeld(config-pool)# show configuration
!
qos buffer pool ingress_lossy_pool
size 32566016
kornfeld(config-pool)# exit
kornfeld(config)# do show qos buffer pool ingress_lossy_pool
-------------------------------------------------------------
Pool Type Size (Byte) Headroom (Byte)
------------------ ------- ------------- -----------------
ingress_lossy_pool ingress 32566016 0Настроим профиль:
kornfeld(config)# qos buffer profile ingress_lossy_profile_opt pool ingress_lossy_pool type static
kornfeld(config-profile)# shared-size 32546560
kornfeld(config-profile)# show configuration
!
qos buffer profile ingress_lossy_profile_opt pool ingress_lossy_pool type static
shared-size 32546560
kornfeld(config-profile)# exit
kornfeld(config)# do show qos buffer profile ingress_lossy_profile_opt
------------------------------------------------------------------------------------------------------------------------------------------------------------
Profile Pool Reserved Size(Byte) Shared Mode Shared Size(Byte or %) Xoff(Byte) Xon(Byte) Xon-offset(Byte)
------------------------- ------------------ --------------------- ------------- ------------------------ ------------ ----------- ------------------
ingress_lossy_profile_opt ingress_lossy_pool 0 static 32546560 0 0 0Привяжем этот профиль ко всем портам всего коммутатора:
kornfeld# configure terminal
kornfeld(config)# interface range Ethernet 1-82
%Info: Configuring only existing interfaces in range
kornfeld(conf-if-range-eth**)# qos-buffer priority-group 0-2,4-7 profile ingress_lossy_profile_opt
kornfeld(conf-if-range-eth**)# exit
kornfeld(config)# do show qos buffer interface Ethernet 1 priority-group
Ethernet1
-------------------------------------------
Priority-group Profile
---------------- -------------------------
0 ingress_lossy_profile_opt
1 ingress_lossy_profile_opt
2 ingress_lossy_profile_opt
3 ingress_lossy_profile
4 ingress_lossy_profile_opt
5 ingress_lossy_profile_opt
6 ingress_lossy_profile_opt
7 ingress_lossy_profile_optПривяжем профили UPLINK-profile и SERVERS-profil к группе приоритета 3 у портов к серверам и аплинкам:
kornfeld(config)# interface range Ethernet 1-5
%Info: Configuring only existing interfaces in range
kornfeld(conf-if-range-eth**)# qos-buffer priority-group 3 profile SERVERS-profile
kornfeld(conf-if-range-eth**)# interface range Ethernet 48-49
%Info: Configuring only existing interfaces in range
kornfeld(conf-if-range-eth**)# qos-buffer priority-group 3 profile UPLINK-profile
kornfeld(conf-if-range-eth**)# exit
kornfeld(config)#Привяжем профиль egress_lossless_profile к очереди 3 у портов к серверам и аплинкам:
kornfeld(config)# interface range Ethernet 1-5,48-49
%Info: Configuring only existing interfaces in range
kornfeld(conf-if-range-eth**)# qos-buffer unicast-queue 3 profile egress_lossless_profile
kornfeld(conf-if-range-eth**)#Проверим настройки на портах на примере двух портов:
kornfeld# show qos buffer interface Ethernet 1 priority-group
Ethernet1
-------------------------------------------
Priority-group Profile
---------------- -------------------------
0 ingress_lossy_profile_opt
1 ingress_lossy_profile_opt
2 ingress_lossy_profile_opt
3 SERVERS-profile
4 ingress_lossy_profile_opt
5 ingress_lossy_profile_opt
6 ingress_lossy_profile_opt
7 ingress_lossy_profile_opt
kornfeld# show qos buffer interface Ethernet 1 unicast-queue
Ethernet1
--------------------------------
Queue Profile
------- -----------------------
UC0 egress_lossy_profile
UC1 egress_lossy_profile
UC2 egress_lossy_profile
UC3 egress_lossless_profile
UC4 egress_lossy_profile
UC5 egress_lossy_profile
UC6 egress_lossy_profile
UC7 egress_lossy_profile
kornfeld# show qos buffer interface Ethernet 48 priority-group
Ethernet48
-------------------------------------------
Priority-group Profile
---------------- -------------------------
0 ingress_lossy_profile_opt
1 ingress_lossy_profile_opt
2 ingress_lossy_profile_opt
3 UPLINK-profile
4 ingress_lossy_profile_opt
5 ingress_lossy_profile_opt
6 ingress_lossy_profile_opt
7 ingress_lossy_profile_opt
kornfeld# show qos buffer interface Ethernet 48 unicast-queue
Ethernet48
--------------------------------
Queue Profile
------- -----------------------
UC0 egress_lossy_profile
UC1 egress_lossy_profile
UC2 egress_lossy_profile
UC3 egress_lossless_profile
UC4 egress_lossy_profile
UC5 egress_lossy_profile
UC6 egress_lossy_profile
UC7 egress_lossy_profileВсе верно. Оценим ограничения примененных настроек:
kornfeld# show qos buffer limits
Total buffer size in bytes: 33030000
Pools Headroom limits:
Total - Total Headroom size in pool in bytes, Used - Sum xoff size using by profiles,
Percent - The percentage of the used size of the Headroom buffer by profiles, Status - Normal or Warning if overbooking
-----------------------------------------------------------
Pools name Total Used Percent Status
--------------------- ------- ------ --------- --------
ingress_lossless_pool 139520 139520 100% Warning
Pools reserved size limits (Byte):
Total - Total pool size without Headroom, Reserved - Total reserved size using by profiles, Shared - Total shared size using for profiles
-----------------------------------------------------
Pools name Total Reserved Shared
--------------------- -------- ---------- --------
egress_lossless_pool 16777216 0 16777216
egress_lossy_pool 15409152 0 15409152
ingress_lossless_pool 16637696 0 16637696
ingress_lossy_pool 32566016 0 32566016В выводе видно, что Headroom для пула используется оптимально. Для поддержки lossless-трафика требуется включить PFC на тех приоритетах, по которым будет идти трафик. Включаем PFC для третьего приоритета на портах к серверам и аплинках:
kornfeld(config)# interface range Ethernet 1-5,48-49
%Info: Configuring only existing interfaces in range
kornfeld(conf-if-range-eth**)# pfc priority 3
kornfeld(conf-if-range-eth**)#
kornfeld(conf-if-range-eth**)# exit
kornfeld(config)# exit
kornfeld# show pfc interface
---------------------------
PFC Interface Priority
--------------- ----------
Ethernet1 3
Ethernet2 3
Ethernet3 3
Ethernet4 3
Ethernet5 3
Ethernet48 3
Ethernet49 3
Total: 7Задача выполнена.
Что еще почитать о разработке коммутатора KORNFELD:
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.