Алгоритм Нейгла

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

Алгоритм Нейгла — назван в честь Джона Нейгла, является средством повышения эффективности работы сетей TCP/IP, позволяющим уменьшить количество пакетов, которые должны быть отправлены по сети.

Документ Нейгла, Управление Перегрузкой IP/TCP Сетей (RFC 896) описывает то, что он назвал «проблемой небольших пакетов», которая заключается в том, что приложение неоднократно посылает данные небольшими порциями, часто размером в 1 байт. Так как TCP пакеты имеют 40 байт заголовка (20 байт TCP, 20 байт IPv4), это приводит к тому, что передается пакет размером 41 байт, несущий в себе 1 байт полезной информации, т.е. к огромным накладным расходам. Эта ситуация часто встречается в сессии Telnet, где большинство нажатий клавиш генерируют один байт данных, который немедленно передается. Кроме того, по медленным каналам связи многие такие пакеты могут находиться в пути в одно и то же время, что может привести к перегруженности сети.

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

Алгоритм[править | править вики-текст]

if there is new data to send
  if the window size >= MSS and available data is >= MSS
    send complete MSS segment now
  else
    if there is unconfirmed data still in the pipe
      enqueue data in the buffer until an acknowledge is received
    else
      send data immediately
    end if
  end if
end if

где MSS — максимальный размер блока данных для TCP-пакета. MSS зависит от MTU.

Этот алгоритм плохо взаимодействует с технологией TCP с отложенным подтверждением, которая была представлена в TCP примерно в то же время, в начале 1980-х. Если приложение, использующее оба алгоритма, устанавливает два последовательных write — соединения TCP, а затем read, то последнее не будет выполнено, пока данные из второго write не достигнут места назначения. В результате получается постоянная задержка до 500 мс, «задержка ACK». По этой причине TCP реализация обычно предоставляет приложениям интерфейс для отключения алгоритма Нейгла (опция TCP_NODELAY).

«На уровне пользователя нужно избегать последовательности „запись-запись-чтение“ на сокетах. „Запись-чтение-запись-чтение“ будет работать хорошо. „Запись-запись-запись“ тоже. Но „запись-запись-чтение“ все ухудшит. Так что, если вы можете, то сохраняйте в буфер ваши небольшие пакеты TCP с данными для записи, а затем отправляйте их все сразу. Если вы используете стандартный пакет UNIX ввода-вывода и „вымывание из буфера“ данных для записи перед каждым чтением, чтение обычно работает нормально.»

Проблему передачи небольших данных (tinygram problem) и «синдром узкого потока» (Silly window syndrome) часто путают. Tinygram problem проявляется, когда окно почти пусто. Silly window syndrome проявляется, когда оно почти заполнено.

Негативное влияние на передачу больших данных для записи[править | править вики-текст]

Алгоритм применим для данных любого размера. Если данные для записи охватывают 2n пакетов, то последний пакет будет удержан в ожидании ACK предыдущего пакета. В любом протоколе приложений типа запрос-ответ, где данные запроса могут быть больше, чем пакет, это может искусственно наложить несколько сотен миллисекунд задержки между запросом и ответом, даже если запрашивающий будет сохранять в буфер данные запроса перед отправкой. В этом случае запрашивающий должен отключить алгоритм Нейгла. Если данные ответа могут быть больше, чем пакет, ответчику также необходимо отключить алгоритм Нейгла, чтобы запрашивающий оперативно получал весь ответ.

Таким образом, алгоритм Нейгла позволяет защититься от небрежно написанного приложения, но он не пойдет на пользу тщательно написанному, которое уделяет надлежащее внимание буферизации; для такого приложения алгоритм либо не будет давать никакого эффекта, либо будет давать отрицательный эффект от применения.

Взаимодействие с системами реального времени[править | править вики-текст]

Приложения, для которых важно актуальное время ответа, могут плохо работать с алгоритмом Нейгла. Такие приложения, как сетевые многопользовательские игры, предполагают, что какие-либо действия в игре отправляется сразу, тогда как алгоритм целенаправленно задерживает передачу, увеличивая эффективность использования полосы пропускания сети за счет задержки. По этой причине приложения с низкой пропускной способностью срочных передач обычно используют TCP_NODELAY, чтобы обойти задержки алгоритма Нейгла.

Другим вариантом в данном случае является использование UDP.

Ссылки[править | править вики-текст]

  1. Boosting Socket Performance on Linux
  2. TCP Performance problems caused by interaction between Nagle's Algorithm and Delayed ACK
  3. Bug 17868 - Some Java applications are slow on remote X connections