Наглинг
Наглинг — это техника оптимизации передачи данных в компьютерных сетях, заключающаяся в накоплении мелких пакетов данных в буфере перед отправкой, с целью уменьшения накладных расходов на передачу служебной информации. Алгоритм, названный в честь Джона Нэгла (John Nagle), который впервые описал его в 1984 году в спецификации RFC 896, позволяет повысить эффективность использования пропускной способности сети, особенно в протоколах, ориентированных на соединение, таких как TCP.
История и предпосылки создания
В ранних компьютерных сетях, в частности в ARPANET, передача данных была дорогостоящей с точки зрения накладных расходов. Каждый отправленный пакет содержал заголовок (обычно 40 байт для TCP/IP), который не зависел от размера полезных данных. При передаче большого количества мелких сообщений, например, при вводе символов в telnet-сессии или при отправке коротких команд в протоколах прикладного уровня, эффективность использования сети резко падала. Например, отправка одного байта данных требовала передачи 41 байта (40 байт заголовка + 1 байт данных), что составляло накладные расходы в 4000%.
Джон Нэгл, работая в компании Ford Aerospace, предложил алгоритм, который решал эту проблему для протокола TCP. Его идея заключалась в том, чтобы задерживать отправку мелких пакетов, объединяя их в один более крупный сегмент, что значительно снижало количество передаваемых заголовков.
Принцип работы алгоритма Нэгла
Алгоритм Нэгла применяется на стороне отправителя и регламентирует, когда можно отправлять новый сегмент TCP. Основные правила выглядят следующим образом:
- Если в буфере отправки есть неподтверждённые данные (то есть данные, которые уже отправлены, но ещё не получен ACK от получателя), то новый мелкий пакет (размером меньше, чем MSS — Maximum Segment Size) не отправляется немедленно. Он помещается в буфер.
- Отправка накопленных данных происходит только в одном из трёх случаев:
- Получено подтверждение (ACK) на все ранее отправленные данные.
- Накопленный объём данных в буфере достиг размера MSS.
- Прошёл определённый тайм-аут (обычно около 200 миллисекунд), что предотвращает бесконечную задержку.
Таким образом, алгоритм Нэгла фактически «склеивает» несколько мелких запросов на отправку в один большой сегмент, что резко снижает количество пакетов в сети. Это особенно эффективно для приложений, которые генерируют данные небольшими порциями, например, для протоколов Telnet, SSH или некоторых игровых серверов.
Взаимодействие с алгоритмом отложенного подтверждения (Delayed ACK)
Алгоритм Нэгла часто вступает в конфликт с другим механизмом оптимизации TCP — алгоритмом отложенного подтверждения (Delayed ACK), описанным в RFC 1122. Этот алгоритм предписывает получателю не отправлять ACK немедленно после получения каждого пакета, а задерживать его на некоторое время (обычно до 200 мс), чтобы объединить подтверждение с ответными данными, если они есть.
Проблема возникает, когда оба алгоритма работают одновременно:
- Отправитель (с алгоритмом Нэгла) отправляет небольшой пакет и ждёт ACK, прежде чем отправить следующий.
- Получатель (с Delayed ACK) получает пакет, но не отправляет ACK немедленно, ожидая, что приложение скоро отправит ответные данные.
- В результате отправитель не может отправить новые данные, пока не получит ACK, а получатель не отправляет ACK, пока не получит новые данные или не истечёт таймер.
Это приводит к так называемому «синдрому глупого окна» (Silly Window Syndrome) в его крайней форме, когда соединение на некоторое время (до 200 мс) фактически останавливается. Для решения этой проблемы в современных стеках TCP используются различные эвристики, например, отправитель может игнорировать алгоритм Нэгла, если он уже отправил данные и ожидает ACK дольше определённого времени.
Проблемы и критика
Несмотря на свою полезность, алгоритм Нэгла не является универсальным решением. Его применение может приводить к заметным задержкам в приложениях, чувствительных к времени отклика (latency-sensitive).
Основные недостатки:
- Задержка ввода-вывода: Для интерактивных приложений (например, удалённый рабочий стол, онлайн-игры, финансовые торговые системы) задержка даже в 200 мс может быть критичной. Пользователь может ощущать «залипание» клавиш или задержку в отображении действий.
- Конфликт с протоколами прикладного уровня: Некоторые протоколы, такие как HTTP/1.1, используют механизмы конвейеризации (pipelining), которые предполагают отправку нескольких запросов без ожидания ответа. Алгоритм Нэгла может нарушить эту логику, задерживая отправку второго запроса до получения ACK на первый.
- Проблемы с Nagle и Delayed ACK: Как описано выше, совместная работа двух алгоритмов может приводить к нежелательным паузам.
Отключение алгоритма Нэгла
Для приложений, где задержка важнее экономии трафика, предусмотрена возможность отключения алгоритма Нэгла. В сокетах TCP для этого используется флаг TCP_NODELAY. При его установке каждый вызов send() или write() приводит к немедленной отправке данных, даже если они малы. Это гарантирует минимальную задержку, но увеличивает количество пакетов и накладные расходы.
Примеры приложений, где TCP_NODELAY обычно включается:
- Онлайн-игры (шутеры, стратегии реального времени).
- Протоколы удалённого рабочего стола (RDP, VNC).
- Финансовые торговые системы.
- Некоторые реализации VoIP (голос поверх IP).
Альтернативы и современное состояние
С развитием сетей и увеличением пропускной способности проблема мелких пакетов стала менее острой для многих приложений. Однако алгоритм Нэгла по-прежнему включён по умолчанию в большинстве операционных систем (Windows, Linux, macOS) и является стандартным поведением стека TCP.
В качестве альтернативы для приложений, которым требуется баланс между задержкой и эффективностью, иногда используется алгоритм Нэгла с модифицированными таймерами или комбинация с другими методами управления потоком. В современных высокопроизводительных сетях (например, в дата-центрах) часто предпочитают полностью отключать алгоритм Нэгла и полагаться на другие механизмы, такие как увеличение размера буфера или использование протоколов с меньшими накладными расходами (например, QUIC, UDP).
Источники
- RFC 896 — «Congestion Control in IP/TCP Internetworks» (John Nagle, 1984).
- RFC 1122 — «Requirements for Internet Hosts — Communication Layers» (IETF, 1989).
- Стивенс, У. Р. «TCP/IP Illustrated, Volume 1: The Protocols». Addison-Wesley, 1994.
- Документация по сокетам и флагу
TCP_NODELAYв операционных системах Linux, Windows и macOS.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →