Nagle’s algorithm и TCP_NODELAY — когда включать и выключать

5 минут чтения
Средний рейтинг статьи — 4.6

При работе с TCP-соединениями важную роль играет не только пропускная способность сети, но и то, как именно отправляются данные. Даже если приложение шлёт данные маленькими кусками, TCP может объединять их или, наоборот, отправлять сразу. За это поведение отвечает алгоритм Нейгла (Nagle’s algorithm) и опция TCP_NODELAY.

Понимание того, как они работают, критично для оптимизации сетевых приложений — от веб-серверов до игровых и real-time систем.

Проблема «маленьких пакетов»

TCP изначально проектировался так, чтобы эффективно использовать сеть. Если приложение отправляет много маленьких сообщений (например, по несколько байт), это приводит к:

  • большому количеству TCP-пакетов
  • увеличению накладных расходов (headers)
  • перегрузке сети

Такие пакеты называют tinygrams.

Чтобы бороться с этим, был предложен алгоритм Нейгла.

Как работает алгоритм Нейгла

Суть проста: не отправлять новые маленькие пакеты, пока не подтверждён предыдущий.

Правило можно сформулировать так:

  • если есть неподтверждённые данные (unacknowledged data), TCP буферизует новые маленькие записи
  • как только приходит ACK — накопленные данные отправляются

В результате:

  • уменьшается количество пакетов
  • повышается эффективность сети

Но есть и обратная сторона.

Проблема задержек (latency)

Алгоритм Нейгла может добавлять задержки, потому что данные ждут ACK перед отправкой.

Это особенно заметно, если:

  • приложение отправляет маленькие сообщения
  • ACK задерживаются (например, из-за delayed ACK на другой стороне)

В худшем случае возникает «залипание» (stall), когда клиент ждёт ACK, а сервер ждёт новые данные.

Что делает TCP_NODELAY

Опция TCP_NODELAY отключает алгоритм Нейгла.

Когда она включена:

  • данные отправляются сразу
  • TCP не ждёт ACK
  • маленькие пакеты не буферизуются

Это снижает latency, но увеличивает количество пакетов.

Когда включать TCP_NODELAY

Отключать Nagle (то есть включать TCP_NODELAY) стоит, если важна минимальная задержка.

Типичные случаи:

Real-time приложения

  • онлайн-игры
  • VoIP
  • чаты
  • стриминг управления

Здесь важна скорость доставки каждого сообщения, даже если оно маленькое.

Интерактивные протоколы

Например:

  • SSH
  • Telnet

Пользователь вводит символы, и важно, чтобы они сразу отправлялись.

RPC и API с маленькими payload

Если запросы/ответы маленькие и частые, задержки от Nagle могут сильно влиять на время отклика.

Когда НЕ стоит отключать Nagle

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

Передача больших данных

  • загрузка файлов
  • стриминг больших блоков

Здесь данные и так отправляются крупными сегментами.

Высоконагруженные системы

Если сервер обслуживает тысячи соединений, большое количество мелких пакетов может:

  • увеличить нагрузку на сеть
  • повысить нагрузку на CPU

Batch-обработка

Если приложение может буферизовать данные само, Nagle помогает дополнительно оптимизировать передачу.

Взаимодействие с delayed ACK

Особенно интересен эффект взаимодействия Nagle и delayed ACK.

Delayed ACK — это механизм, при котором получатель не сразу отправляет подтверждение, а ждёт немного, чтобы объединить ACK.

Если одновременно:

  • включён Nagle
  • включён delayed ACK

может возникнуть задержка до ~200 мс:

  1. отправитель ждёт ACK
  2. получатель ждёт данные, чтобы отправить ACK

Это классическая проблема latency в TCP.

TCP_NODELAY помогает её избежать.

Практика: что делают современные системы

В реальных приложениях часто используют гибридный подход:

  • включают TCP_NODELAY для интерактивных соединений
  • оставляют Nagle для bulk-трафика

Например:

  • веб-сервер может отключать Nagle для keep-alive соединений
  • игровые серверы почти всегда используют TCP_NODELAY

Итог

Алгоритм Нейгла — это оптимизация для уменьшения количества маленьких пакетов и повышения эффективности сети. Однако он может увеличивать задержки.

TCP_NODELAY даёт противоположный эффект: минимальную задержку ценой большего числа пакетов.

Выбор между ними зависит от задачи:

  • нужна минимальная latency — включаем TCP_NODELAY
  • важна эффективность и пропускная способность — оставляем Nagle

Понимание этого баланса позволяет существенно улучшить поведение сетевых приложений.

5 минут чтения
Средний рейтинг статьи — 4.6

Настроить мониторинг за 30 секунд

Надежные оповещения о даунтаймах. Без ложных срабатываний