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

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

Алгоритм Нейгла — назван в честь Джона Нейгла, является средством повышения эффективности работы сетей 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) часто путают. Проблема передачи небольших данных проявляется, когда окно почти пусто. Синдром узкого потока проявляется, когда оно почти заполнено.

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

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

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

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

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

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

Литература[править | править код]

  • Peterson, L. L. and Davie, B. S. Computer Networks: A Systems Approach. — Morgan Kaufmann, 2007. — P. 402—403. — ISBN 9780123705488.

Ссылки[править | править код]