Излишняя сетевая буферизация
Излишняя сетевая буферизация (англ. bufferbloat) — это нежелательная задержка, возникающая из-за того, что маршрутизатор или другое сетевое оборудование хранит в буфере слишком много сетевых пакетов. Излишняя буферизация также способна вызывать джиттер, а также снижать общую пропускную способность сети. Если маршрутизатор или коммутатор настроен на использование чрезмерно больших буферов, даже высокоскоростные сети могут практически стать непригодными для использования многими интерактивными приложениями, такими как голос по IP, потоковое аудио, онлайн-игры, а также обычный просмотр веб-страниц.
Буферизация
Некоторые производители оборудования для связи проектировали избыточно большие буферы в своих сетевых устройствах. В таких устройствах избыток буферизации возникает при перегрузке сетевого канала, из-за чего пакеты долго простаивают в больших буферах. В системе с режимом обслуживания очередей «первым пришёл — первым обслужен» (FIFO) чрезмерно большие буферы приводят к увеличению длины очереди и задержкам без улучшения пропускной способности сети. Избыточная буферизация также может появиться при прохождении пакетов через сверхмедленное соединение, препятствующее своевременной доставке других пакетов.
Феномен избыточной буферизации был описан ещё в 1985 году[1], однако широкое внимание к нему появилось в 2009 году[2].
По некоторым данным, самой частой причиной высокой задержки (так называемого «лага») в онлайн-играх является локальная избыточная сетевая буферизация в домашних сетях. Высокая задержка делает невозможным современный онлайн-гейминг[3].
Сложившееся в отрасли правило для производителей сетевого оборудования диктовало подбирать такие размеры буфера, чтобы можно было буферизовать как минимум 250 мс трафика, проходящего через устройство. Например, интерфейс Gigabit Ethernet в маршрутизаторе требовал бы относительно крупного буфера объёмом 32 МБ[4]. Подобная настройка приводит к некорректной работе алгоритма управления перегрузкой TCP. Буферам требуется время, чтобы опустеть, прежде чем алгоритм управления перегрузкой перезапустится, соединение TCP разгонится до максимальной скорости и снова наполнит буферы[5]. Избыточная буферизация вызывает проблемы вроде высокой и изменчивой задержки, а также создаёт бутылочные горлышки, когда весь буфер заполняется пакетами одного TCP-потока и остальные пакеты начинают теряться[6].
Буфер влияет на задержку только тогда, когда он действительно используется. Иными словами, излишне большой буфер критичен ровно тогда, когда обслуживаемое им соединение становится «узким местом». Размер такого буфера можно оценить в миллисекундах с помощью утилиты ping, встроенной в большинство операционных систем. Сначала следует многократно отправить ping другому хосту, а затем пару раз запустить и остановить загружаемый с этого же хоста файл. По задумке, алгоритм TCP congestion avoidance быстро заполнит бутылочное горлышко на пути. Если при скачивании наблюдается заметный рост времени отклика по ping, это свидетельствует о наличии избытка буферизации на активном направлении. Максимальное увеличение времени задержки даст грубую оценку размера буфера в условиях загрузки.
В приведённом выше примере использование расширенной утилиты трассировки пути вместо обычного ping позволит обнаружить не только наличие, но и положение избыточного буфера на пути передачи данных. Traceroute визуализирует маршрут пакета и время его прохождения через каждый узел, позволяя точно определить «узкое место» в сети[7].
Механизм появления
Большинство алгоритмов управления перегрузкой TCP оценивают пропускную способность соединения, измеряя появление потерь пакетов. Алгоритмы ускоряют передачу данных до первых потерь, затем снижают скорость отправки. В идеале они подстраивают скорость передачи так, чтобы она соответствовала максимальной пропускной способности канала. Однако обратная связь о потере пакетов должна поступать своевременно. Если заполнить большой буфер, пакеты перестают теряться, зато прибывают к получателю с большой задержкой. Из-за этого TCP не сбавляет темпа передачи, и буфер продолжает переполняться; новые пакеты начинают отбрасываться только тогда, когда буфер полностью заполнен. В этот момент TCP может решить, что маршрут изменился, и вновь начать ускоренный поиск рабочего режима[8].
Пакеты складываются в сетевой буфер перед передачей; проблемы возникают, когда пакеты начинают отбрасываться только после полного заполнения буфера. На ранних маршрутизаторах буферы были малы, наполнялись быстро и приводили к раннему срабатыванию контроля перегрузок TCP, что позволяло системе быстро восстанавливаться. В современных маршрутизаторах буферы могут хранить данные за несколько секунд, из-за чего TCP не замечает перегрузки сети и не регулирует скорость вплоть до полного переполнения буфера.
Все соединения, проходящие через заполненный буфер, испытывают идентичную задержку — то есть страдают все протоколы и приложения, в том числе использующие UDP[9].
Влияние на приложения
Независимо от требуемой полосы пропускания, любые сервисы, чувствительные к задержкам и джиттеру, страдают от избыточной буферизации. К таким сервисам относятся цифровая телефония (VoIP), онлайн-игры, видеочат и другие интерактивные приложения: радио, видео по требованию, удалённый вход в систему.
При наличии избытка буферизации и высоких нагрузках даже обычная загрузка веб-страниц может занимать несколько секунд, а простые DNS-запросы могут завершаться ошибкой по тайм-ауту[10]. Любое TCP-соединение может разорваться, а UDP-пакеты могут быть утеряны. Поскольку продолжение TCP-потока зависит от своевременного получения подтверждений (ACK) в обратном направлении, избыток буферизации на канале отправки приводит к сбоям в приложениях приёма, так как подтверждения не доходят к серверу вовремя.
Обнаружение (детектирование)
Тест DSLReports Speedtest[11] был простым инструментом с отдельной оценкой избыточной буферизации. Весь сайт DSLReports перестал работать 26 марта 2025 года. Другой онлайн-инструмент — ICSI Netalyzr[12] — также позволял выявлять избыток буферизации и множество других сетевых ошибок[13]. Сервис был закрыт в марте 2019 года. На сайте bufferbloat.net размещён список инструментов и процедур для выявления избытка буферизации, приводящего к снижению скорости соединения[14].[15]
Решения и методы смягчения
Существует ряд технических решений этой проблемы, условно разделяемых на решения в самой сети и реализуемые на конечных устройствах. Чаще всего эти подходы сочетаются, поскольку проблема может возникнуть из-за комбинации быстрых и медленных сетевых участков.
Сетевые решения основаны на различных алгоритмах управления очередями (AQM). Такой подход разрабатывается IETF в рабочей группе по AQM[16]. Наиболее заметные примеры:
- Ограничение длины очереди IP-пакетов (см. TCP tuning)
- Активные алгоритмы управления очередями, такие как CoDel, PIE[17].
- Гибридные алгоритмы управления очередями и планирования пакетов, такие как FQ-CoDel[18].
- Внесение изменений в стандарт DOCSIS[19] для поддержки управления буфером в кабельных модемах[10].
- Интеграция управления очередями (FQ-CoDel) в подсистему Wi-Fi в Linux, так как Linux широко используется в беспроводных точках доступа[20].
Примеры решений на стороне конечных устройств:
- Алгоритм управления перегрузкой BBR для TCP.
- Micro Transport Protocol, используемый многими клиентами BitTorrent.
- Технологии, уменьшающие число соединений, такие как HTTP pipelining и HTTP/2 вместо классического HTTP[10].
Проблему также можно смягчить, уменьшая размер буферов в операционной системе[10] и сетевом оборудовании, однако оптимальный размер буфера зависит от пропускной способности канала и может быть разным для разных направлений связи.
Использование DiffServ (разделение очередей по приоритетам) позволяет отдавать предпочтение трафику с низкой задержкой, перекладывая обработку перегруженных очередей на менее критичные потоки[21].
Оптимальный размер буфера
Чтобы даже для соединений с самой длинной задержкой TCP обеспечивалось пропорциональное использование полосы, размер буфера должен быть не менее произведения полосы и задержки делённого на квадратный корень из числа одновременных потоков[4][22]. Типичное практическое правило: буфер должен вмещать 50 мс трафика на линейной скорости[23], однако многие бытовые коммутаторы располагают буфером всего на 1 мс[24], что приводит к дополнительным потерям пропускной способности на соединениях с большой задержкой при локальных конфликтах.
Примечания
Литература
- BufferBloat: What's Wrong with the Internet? — обсуждение с Винтом Серфом, Ваном Джекобсоном, Ником Уивером и Джимом Геттисом
- Размер TSO и планировщик FQ (Джонатан Корбет, LWN.net)


