Shallow vs Deep Buffers

Буферы - это то место, где пакеты можно похранить, вкачав в них смертельную порцию задержки.
Как сказали в видео Packet Pushers - буферы - это религия. Хотя, скорее всего, неортодоксальная, а возможно даже секта.

Чуть позже мы поговорим о том, что такое хорошо, а что такое плохо. А пока посмотрим на реализации.

Shallow - неглубокие - это буферы размером до 100МБ. Обычно это встроенная в кристалл on-chip память - OCB - On-Chip Buffer. Deep - счёт уже идёт на гигабайты. Обычно off-chip и подключается к чипу по отдельной шине. И нет ничего посередине.

За последние лет десять производительность чипов выросла на порядки, трафика они теперь перемалывают терабиты в секунду вместо единиц гигабит. А размер памяти не то что не поспевает за этим ростом, он фактически почти стоит на месте.
Давайте грубо прикинем: если для гигабитного порта буфер размером 16 мегабайт мог абсорбировать всплеск трафика длительностью примерно 100 мс, то для 100Гб/с - всего лишь 1мс. И это только один порт, фактически же плотность портов тоже растёт и максимальная комплектация для одночипового устройства сегодня - 64 порта 400Гб/с - или 25,6 Тб/с полосы пропускания.
Используя только 64 МБ буфер, такой чип сможет хранить трафик 0.000005 c или 5 мкс.

Такие буферы порой даже называют Extremely shallow buffers.

Их воистину миниатюрный объём обусловлен в первую очередь тем, что они в прямом смысле встроены в чип. Такая память является составной частью микросхемы, и каждый дополнительный мегабайт, разумеется, будет обходиться в лишнюю тысячу долларов, больший размер и тепловыделение. Для справки Broadcom Trident 4 содержит 21 миллиард транзисторов, изготовленных по 7нм техпроцессу (это меньше размера капсида любого существующего вируса) на нескольких квадратных сантиметрах.
Логично вытекающим следствием является скорость работы с этой памятью - она должна соответствовать производительности чипа.
https://fs.linkmeup.ru/images/articles/buffers/trident4_memory.png

Очевидно, что не для всех задач такие маленькие буферы подходят. В частности модульные коробки с VOQ явно не могут позволить себе дробить 64 Мб на несколько тысяч очередей (на самом деле могут).

Поэтому рынок предлагает решения с большой внешней памятью (Deep Buffers), размер которой начинается от 1ГБ (обычно от 4ГБ).
Согласно этой таблице существуют коммутаторы (Arista 7280QR-C48) с фантастическими 32-хгигабайтовыми буферами - это уже все сезоны Рика и Морти в неплохом качестве. Но это уже история про | VOQ - всё-таки это память не одного чипа. На моём первом ПК такого объёма был жёсткий диск.
Как такая память реализована зависит уже от чипа и коробки.
Например, Broadcom Jericho+ сгружает пакеты во внешнюю память в размере 4ГБ. Это обычная широко известная GDDR5, использующаяся в видеокартах.

Jericho2 несёт на борту новейшую память HBM2 - High Bandwidth Memory - размером 8ГБ.

А вот и фото Jericho2:

Juniper PTX и QFX10000 используют чип Q5 собственного производства с внешней памятью - HMC - Hybrid Memory Cube - в размере 4ГБ.

А вот так выглядит сетевой процессор Cisco с внешней памятью:

Перечислять можно и дальше.
Что здесь важно отметить, что внешняя память тоже не даётся бесплатно. Во-первых, цена таких решений значительно выше. Во-вторых, пропускная способность обычно ниже. И основное ограничение - канал между чипом коммутации и чипом памяти. Для производимых массово чипов, вроде GDDR5 полоса не превышает 900ГБ в режиме half-duplex. Но это чип, явно не заточенный под задачи сетевых сервисов.

Кастомный джуниперовский HMC обещает 1,25 Тб/с в обоих направлениях.

Если верить вики, то HBM 2-го поколения, используемый в последнем чипе Broadcom Jericho2, выдаёт порядка 2Тб/с.

Но это всё ещё далеко от реальной производительности сетевого ASIC. Фактически шины до этой внешней памяти является узким местом, которое и определяет производительность чипа.

Important

Когда-то мир был лучше и было строгое разделение - Shallow Buffer - это встроенная On Chip память, Deep Buffer - внешняя.
С развитием WLP ситуация начинает меняться. Память HBM становится co-packaged в один чип вместе с комутационным асиком. TSV и 3D Advanced Packaging значительно увеличивают пропускную способность. И нередко в перезентациях вендорово можно увидеть “Deep Buffer” и “On Chip” в одной фразе.
Тут нужно быть осторожным, поскольку шина между асиком и памятью, пусть даже они расположены рядышком на одном интерпозере под общей крышкой, всё ещё является узким местом и ограничивает максимальную пропускную способность.

Hybrid Buffering

Поэтому почти все вендоры сегодня практикуют гибридную буферизацию, или, если хотите - динамическую. В нормальных условиях используется только on-chip память, предоставляющая line-rate производительность. А в случае перегрузки пакеты автоматически начинают буферизироваться во внешней памяти. Это позволяет уменьшить стандартные задержки, энергопотребление и в большинстве случаев вписаться в ограниченную полосу пропускания до памяти.

Note

Данный параграф отменяет сказанное выше о том, что on-chip памяти не хватит для VOQ. Фактически в случае гибридной буферизации она всё же дробится на тысячи очередей очень маленькой длины, чтобы обеспечить VOQ. Просто в нормальных условиях этой длины хватает, чтобы пропускать трафик мимо внешней памяти.
При этом в первую очередь начнёт офлоадиться на внешнюю память массивный трафик, идущий в низкоприоритетных очередях, а требовательный к задержками будет по-прежнему пролетать фаст-пасом.

Большие буферы - добро или зло?

В целом это довольно старая дилемма. Подольше похранить или пораньше дропнуть?

Конечно, всем приложениям хочется lossless low-latency сеть. Даже жирному некрасивому торренту. Но так не бывает и кем-то нужно жертвовать.
И мы долгое время живём с инертной мыслью , что часть приложений могут потерпеть задержки, а вот терять трафик совсем не хочется. Не в малой степени этому способствовало и то, что потери - это измеримая характеристика с более или менее понятными границами - потерь быть не должно. А что задержка? Вроде можно чётко сказать, что единицы миллисекунд - это хорошо, а секунды - это плохо. А между ними - зона спекуляций. Как оценить влияние вариаций задержки для рядового TCP-трафика?
Поэтому и спрос на устройства с большими буферами есть - никто не хочет терять трафик.
А теперь я выскажу не самое популярное мнение - потери - это хорошо.
Так уж вышло, что один из транспортных протоколов, фиксирует перегрузки, опираясь на потери.
Дроп в очереди на сетевом устройстве означает, что на нём случился затор - это он не по своему капризу. И будет совсем не лишним, если отправители немного приуменьшат свои congestion window.
Именно так и работают все классические (и не очень) реализации TCP Congestion Control.

Соответственно на устройствах с глубокими буферами во время заторов пакеты будут долго копиться, не отбрасываясь. Когда они всё-таки дойдут до получателя и тот их ACKнет, отправитель не только не снизит скорость, но может даже её увеличить, если у него сейчас режим Slow Start или Congestion Avoidance.

Можно взглянуть и дальше: растущая очередь взвинчивает RTT, что соответственно влечёт за собой увеличение RTO таймеров на отправителях, тем самым замедляя обнаружение потерь.

То есть сеть лишается своего практически единственного инструмента управления перегрузками.
И таким образом архитекторы, пытающиеся решить вопрос заторов на сети путём увеличения буферов, усугубляют ситуацию ещё больше.
Ситуация, описанная выше, называется bufferbloat - распухание буфера.
Википедия иронично замечает:
Проект www.bufferbloat.net иронично определил этот термин, как «ухудшение производительности Интернета, вызванное предыдущими попытками её улучшения»

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

Note

Справедливости ради следует заметить, что современные реализации TCP - BBR2, TIMELY ориентируются не только и не столько на потери, сколько на RTT и BDP.
Гугловый QUIC - надстройку над UDP - следует отнести сюда же.
Внутри фабрики датацентра RTT ультракороткий - зачастую меньше 1 мс. Это позволяет среагировать на потерю очень быстро и купировать перегрузку в её зачатке.
Собственно поэтому практически все ASIC’и для датацентровых коммутаторов имеют только крохотную on-chip память.
Хотя и появилась в последние годы тенденция к глубоких буферам и тут.
И этому даже находится объяснение.
Особая история на границе датацентра (или на устройствах доступа в сети провайдера или на магистральных сетях).
Во-первых, это места, которые обычно заведомо строятся с переподпиской, поскольку WAN-линки дорогие, что автоматически означает, что ситуации, в которых трафика приходит больше, чем способен переварить интерфейс, ожидаемы. А значит нужна возможность пакеты хранить и обрабатывать их в соответствии с приоритетами. Большие буферы позволяют сгладить всплески.
Во-вторых, обычно приложения настолько чувствительные к задержкам, никто не будет пытаться растягивать на этот сегмент. Например, RoCE или распределённое хранилище. Для чуть менее чувствительных, таких как телефония, в больших буферах выделяется приоритетная очередь.
В-третьих, тут задержки на устройстве всё ещё делают основной вклад в общее время доставки, но уже не настолько драматический.

Итак, устройства с большим объёмом памяти годятся в места где заложена переподписка или могут появиться заторы.

Что стоит отметить, так это то, что в датацентрах тоже есть ситуации, в которых 16-64 МБ буферов может не хватить, даже несмотря на отсутствие переподписки.
Два типичных примера - это обработка Big Data и Storage.
Анализ Big Data. Кластера Map-Reduce - это сотни и тысячи машин, которые перемалывают параллельно огромные массивы данных по заданию Master-узла, заканчивают примерно одинаково и все разом начинают возвращать ответы на Master-узел. Ситуация называется Incast. Длится она порядка нескольких десятков миллисекунд и потом исчезает.
On-chip память неспособна вместить эти данные - значит будет много дропов, значит ретрансмиты, значит общее снижение производительности.

Storage. Это штука крайне чувствительная к потерям и тоже гоняющая массивные объёмы данных. В случае хранилки тоже лучше не терять ничего. Но обычно она при этом и к задержкам предъявляет строгие требования, поэтому такие приложения обсудим пониже.

Однако при этом крайне редко они единственные потребители сети в датацентрах, другим приложениям нужна низкая задержка.

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

Но в любой ситуации лучше следовать правилу: use shallow ASIC buffers when you can and use deep buffers when you must.

Критика глубоких буферов:

Кстати, показательная таблица типичных задержек: