logo

компьютеры серверы оргтехника

                                                   

заявка на товар             прайс от 08.09.2017        zakaz@vremyaitb.ru

КОРЗИНА Товаров: Предзаказ: на сумму: 0 руб.
0 шт.
0 шт.

Информеры - курсы валют
Рейтинг@Mail.ru
Яндекс.Метрика
RSS импорт: www.rss-script.ru
 
Главная > Оптимизация работы протокола ТСР в распределенных сетях

Оптимизация работы протокола ТСР в распределенных сетях

« Назад

Оптимизация работы протокола ТСР в распределенных сетях   07.10.2012 10:16

В истории человечества транспорт всегда занимал одно из определяющих мест. Не стал он исключением и в информационных системах, особенно в сетях на базе протокола ТСР/IP. В этом случае пристальное внимание разработчиков направлено на постоянное совершенствование методов доставки информации. Данная статья призвана помочь администраторам сетей понять тонкости работы транспортной системы.

Некорректное «поведение» почтовой системы Microsoft Exchange в распределенной сети с облаком frame relay стало для автора стимулом, побудившим его обратить особое внимание на работу протокола TCP в сетях под управлением программных продуктов Microsoft. Последующий детальный анализ сбоев показал, что их причина кроется вовсе не в работе почтовой системы, а в громоздкости механизма передачи информации. В частности, многие попытки скопировать «Проводником» с удаленного сервера по frame relay (CIR=32 кбит/с) большой объем данных (несколько сотен мегабайт) заканчивались ошибками передачи.

Эти ошибки возникали из-за слишком высоких «накладных расходов» на служебную информацию. Например, при простой процедуре копирования файлов необходимо установить соединение TCP, инициировать сеанс NetBIOS, произвести обмен служебной информацией протокола SMB и т.д. Другими словами, процедура копирования смахивает на русскую матрешку, так как состоит из вложенных друг в друга протоколов с их компонентами. Каждый протокол при транспортировке этого «милого создания» занимает часть сетевых ресурсов, что в конечном счете приводит к нестабильной работе медленных каналов связи.

К сожалению, проблемы, связанные с транспортировкой данных по распределенной сети, не решаются сами собой. Основным «действующим лицом» в такой сети является ТСР, и вот почему: IP просто предоставляет другим протоколам свои дейтаграммы и не производит решительно никаких действий по повышению производительности, пакеты же более высоких (относительно ТСР) уровней инкапсулируются в поле полезной нагрузки ТСР и терпеливо ждут, когда их доставят приложению-получателю.

Вопрос о производительности сетей под Windows NT открыт до сих пор. Практически во всех учебных пособиях по этой сетевой операционной системе прямо говорится, что не имея высокой квалификации, не следует браться за настройку оптимальной скорости транспорта ТСР (иными словами — изменять значения параметров в системном реестре).

Встречаются и более осторожные утверждения типа «настройка протокола ТСР может не дать ожидаемого эффекта». Думается, что пассивная позиция, основанная на постулате «работает и слава Богу», для современных сетевых администраторов неприемлема. Хочется обратить ваше внимание на то, что многообразие расширений протокола ТСР позволяет администратору творчески подойти к построению и оптимизации своей сети. В системном реестре хранится большое количество параметров, которые позволяют довести сеть «до ума». Одни расширения имеют два состояния — включено по умолчанию или выключено, для других предусмотрено несколько настраиваемых значений. Конечно, надо твердо знать, что можно и нужно настраивать и какие эффекты способна породить произведенная настройка. Документы RFC во многих случаях просто описывают процесс.

Цель настоящей публикации — подробно описать процессы, лежащие в основе тех или иных алгоритмов, выделить наиболее критичные параметры и определить степень их влияния на производительность ТСР. Следует отметить, что углубленное понимание работы механизмов протокола TCP и вопросов его производительности является важным условием успешного внедрения сетевых проектов. Так, при создании крупной распределенной сети на базе ОС Windows NT проектировщику надо внимательно отнестись к планированию загрузки сетевых каналов.

Протокол TCP

Протокол TCP, поддерживаемый всеми приложениями в сетях IP, входит в тройку транспортных протоколов операционной системы Windows NT (рис. 1).

 

Рис. 1. Протокол ТСР в ОС Windows NT 5.0

ТСР дает возможность пользователям среды Windows NT обращаться ко всем доступным сервисам. Наиболее широкий список дополнений и расширений протокола ТСР фирмы Microsoft представлен в операционной системе Windows 2000 (Windows NT 5.0).

Чтобы облегчить восприятие последующего материала, кратко напомним основы протокола ТСР. Минимальная длина заголовка ТСР составляет 20 байт, что позволяет протоколу производить большое количество операций. В дальнейшем изложении чаще других упоминаются три поля заголовка.

Поле «Номер в последовательности» (Sequence Number, SN) определяет номер первого байта в очереди (или последовательности) байтов в текущем сегменте. Исключение составляют случаи, когда установлен бит (флаг) синхронизации SYN. Тогда это поле обозначает начальный номер в последовательности (Initial Sequence Number, ISN), и первый байт данных получает номер очереди ISN + 1.

Поле «Номер подтверждения» (Acknowledgement Number) содержит номер сегмента с подтверждением успешного приема (который отправитель ожидает в ответ на отосланный сегмент) в последовательности получаемых подтверждений. Указанный номер заносится в поле «Номер в последовательности». При этом должен быть установлен контрольный бит подтверждения ACK. После того как соединение установлено, подтверждения посылаются постоянно. Поле «Окно» (Window) содержит объявленный размер окна в байтах.

Назначение большинства полей заголовка ТСР определяется контрольными битами (URG, ACK, PSH, RST, SYN и FIN). Соединения протокола TCP переходят из одного состояния в другое в ответ на определенные события (запросы клиента, поступление сегментов с флагами SYN, ACK, RST, FIN) или по истечении заданного времени. Условно можно выделить три стадии: установление, рабочее состояние и закрытие соединения.

В основном состоянии соединения — ESTABLISHED (соединение установлено) — происходит обмен данными между абонентами. При формировании соединения осуществляется так называемая синхронизация номеров. Рассмотрим этот процесс для станций А и Б. Для синхронизации необходимо выполнить следующие действия.

  1. Станция А отправляет сегмент с флагом SYN и своим номером очереди N станции Б.
  2. Станция Б посылает подтверждение («ваш номер очереди — N») станции А.
  3. Станция Б отправляет сегмент с флагом SYN и своим номером очереди (обозначим его через K) станции А.
  4. Станция А посылает подтверждение («ваш номер очереди — K») станции Б.

Шаги 2 и 3 можно объединить, поэтому такой обмен называется установлением (открытием) соединения с подтверждением трех сообщений. Для надежной передачи данных между прикладными программами по установленным логическим соединениям протокол TCP должен обеспечивать следующие функции:

  • передачу данных;
  • проверку достоверности данных при передаче;
  • управление потоком данных и контроль за перегрузками в сети;
  • разделение каналов связи;
  • обслуживание сформированных соединений;
  • соблюдение установленного приоритета пользователей;
  • обеспечение соответствующего уровня безопасности.

 

Рис. 2. Последовательность этапов передачи (а)
и приема (б) данных

Одновременное использование протокола TCP несколькими прикладными программами, запущенными на одном компьютере, возможно благодаря тому, что он представлен сокетами. В целях сохранения всей совокупности информации, необходимой для формирования и поддержки соединения, каждый раз при его установлении создается структура данных, называемая блоком управления передачей (Transmission Control Block, TCB). Последний поддерживает ряд переменных, определяющих очередность отправления и получения сегментов. К ним, в частности, относятся: SND.UNA — посылка не подтверждена; SND.NXT — послать следующий сегмент; SND.WND — отправить окно сегментов; RCV.NXT — получить следующий сегмент. Чередование этапов отправки и приема данных показано на рис. 2.

Рассмотрим пример использования некоторых переменных. Отправитель, используя переменную SND.NXT, контролирует отправку очередного сегмента из очереди. Получатель с помощью переменной RCV.NXT отслеживает номер следующего поступающего сегмента. В поле переменной SND.UNA отправитель помещает последний номер сегмента, который уже отправлен, но еще не подтвержден. При отсылке нового сегмента отправитель увеличивает значение своей переменной SND.NXT. Получатель при приеме этого сегмента увеличивает значение своей переменной RCV.NXT и посылает подтверждение. При получении подтверждения увеличивается значение переменной SND.UNA отправителя.

Разность величин SND.NXT и SND.UNA может служить мерой задержки сегментов в сети. Переменные изменяются на величину длины поля данных сегмента. Более подробно формат заголовка, назначение полей, флаги, возможные состояния соединения и переменные описаны в RFC 793.

Плавающее окно

Как и большинство протоколов, осуществляющих управление потоком данных (например, HDLC и X.25), TCP использует механизм плавающих окон, который без преувеличения можно назвать основополагающим. Протоколы HDLC и X.25 применяют его в классическом виде — на каждый отправленный блок данных должно быть получено подтверждение. TCP несколько отходит от классической схемы, главный недостаток которой состоит в том, что за один сеанс может быть передан лишь один сегмент. В данном случае под сеансом понимается посылка сегмента и получение подтверждения о его успешном приеме. Такая схема не позволяет работать с максимальной производительностью. Эффективность передачи можно значительно повысить, если разрешить пересылку множества сегментов в одном сеансе с группировкой всех подтверждений об их приеме.

Рассмотрим этот метод подробнее на примере обмена данными между станциями А и Б. Станция Б выделяет буферное пространство для приема n сегментов, которые станция А может отправить, не дожидаясь индивидуальных подтверждений их приема. Для идентификации подтверждений о принятых сегментах каждый из них помечен своим номером в последовательности данных. Станция Б посылает подтверждение о получении текущего сегмента, включающее в себя номер в последовательности следующего ожидаемого сегмента. Это подтверждение косвенно извещает станцию А о том, что станция Б готова принять следующие n сегментов, начиная с указанного номера.

Очевидно, что можно выслать одно подтверждение на несколько сегментов. Например, станция Б получила сегменты 2, 3 и 4, но задержала подтверждения о приеме сегментов 2 и 3 до получения сегмента 4. После посылки подтверждения с номером последовательности 5 станция Б подтверждает получение сегментов 2, 3 и 4 за один раз. Другими словами, станция А соблюдает список номеров сегментов в последовательности, которые ей разрешено посылать, а станция Б поддерживает аналогичный список для сегментов, которые она готова принять. Каждый из этих списков может рассматриваться как окно сегментов. Описанную схему часто называют управлением потоком с использованием плавающего окна.

 

Рис. 3. Сегменты в потоке данных на стороне отправителя (а) и получателя (б)

Поскольку номер в последовательности занимает одно поле в сегменте, диапазон его допустимых значений ограничен. Например, если под него отведено 3 бита, то номер в последовательности может принимать значения от 0 до 7. Соответственно, и сегменты будут нумероваться по модулю 8. Таким образом, для поля последовательности, состоящего из k бит, номера в последовательности лежат в интервале значений от 0 до (2k - 1), а сегменты нумеруются по модулю 2k.

В процессе передачи и приема сегменты проходят ряд промежуточных состояний, представленных на рис. 3. Здесь же показаны направления, в которых движутся границы окон отсылки и приема. Для простоты размер поля «Номер в последовательности» принят равным 3 битам. Затененные прямоугольники указывают на сегменты, которые могут быть посланы. Так, отправитель может передать шесть сегментов, начиная с нулевого. Каждый раз, когда сегмент послан, ширина затененного окна уменьшается; при каждом приеме подтверждения она увеличивается. Сегменты, находящиеся между вертикальной чертой и затененным окном, уже были отправлены, но еще не подтверждены. Отправитель должен хранить копии этих сегментов в своем буфере, чтобы при необходимости передать их повторно. Заметим, что реальный размер окна не обязательно должен совпадать с максимально возможным номером в последовательности.

 

Рис. 4. Пример работы технологии плавающего окна

Рассмотрим следующий пример (рис. 4), который позволяет проследить за обменом информацией. Для наглядности в нем используется трехбитное поле номера в последовательности. Максимальный размер окна в этом случае дает возможность оперировать семью сегментами.

В начале работы размеры окон на станциях А и Б таковы, что станция А может передать семь сегментов, начиная с S 0 , а станция Б — принять такое же их количество. После передачи трех сегментов (S 0 , S 1 и S 2 ) без подтверждения станция А сокращает размер своего окна отсылки до четырех сегментов и сохраняет в буферной памяти копию трех посланных сегментов. Новый размер окна отсылки указывает на то, что станция А может передать четыре сегмента, начиная с S 3 .

Станция Б после получения части сегментов передает сообщение RR3, из которого следует, что все сегменты по S 2 включительно получены и станция Б готова принять S 3 , а также еще шесть сегментов, следующих за ним. Для станции А эта информация эквивалентна разрешению на передачу семи сегментов, начиная с S 3 . Кроме того, станция А может очистить свою буферную память от копий первых трех сегментов, как успешно принятых. Теперь станция А передает S 3 , S 4 , S 5 и S 6 , а cтанция Б в ответ отправляет подтверждение RR4 на получение S 3 и разрешает отослать сегменты от S 4 до S 2 (где S 0 —S 2 относятся уже к следующей последовательности из семи сегментов). Однако на момент получения станцией А этого подтверждения S 4 , S 5 и S 6 уже были посланы, следовательно, она может расширить свое окно отсылки и отправить четыре сегмента, начиная с S 7 (правда, сегменты S 4 —S 6 пока должны оставаться в буфере).

«Узкие места» в сети

В протоколах канального уровня управление потоком данных с использованием плавающего окна дает возможность получателю контролировать скорость работы отправителя. Получатель в этом случае только подтверждает принятые сегменты и расширяет свое окно приема в соответствии с наличием свободного буферного пространства. Скорость передачи данных можно задавать и при работе с протоколом TCP. Для простоты рассмотрим классический вариант, при котором скорость отсылки данных определяется скоростью поступления подтверждения для предыдущего посланного сегмента.

Покажем, что в этом случае скорость поступления подтверждений лимитируется наличием так называемых «узких мест» в сети между отправителем и получателем. «Узким местом» может быть либо сетевое устройство, либо часть канала, пропускная способность которого значительно уступает скоростным показателям сети в целом. Иногда «узким местом» становится станция-получатель.

 

Рис. 5. Примеры логических и физических «узких мест»

«Узкие места» можно разделить на логические и физические (рис. 5). Если отправитель имеет пропускную способность 10 Мбит/с, то канал со скоростью 1,5 Мбит/с между маршрутизаторами становится физическим «узким местом» для работы протокола ТСР. В таком случае после достижения устойчивого режима передачи протокол TCP будет эффективно использовать доступную пропускную способность. Однако гораздо чаще «узкие места» являются логическими и образуются из-за наличия очередей в маршрутизаторах, коммутаторах или на станциях-получателях. Задержки в очередях, как правило, подвержены флуктуациям и усложняют процесс формирования устойчивого потока данных.

Флуктуации задержек, которые образуются в распределенных IP-сетях, затрудняют выбор политики отсылки данных протоколом TCP на стороне отправителя. Если поток имеет слишком маленькую скорость, то распределенная сеть будет задействоваться неэффективно. Если один или несколько отправителей передают данные на повышенной скорости, то другие потоки TCP будут «зажаты» потоками, исходящими от этих отправителей. Наконец, в том случае, когда множество отправителей TCP используют чрезмерно высокую скорость, сегменты начнут теряться либо подтверждения будут поступать со значительной задержкой, что вызовет ненужные повторные передачи. Более того, чем больше сегментов транспортируется повторно, тем выше нагрузка на сеть, что, в свою очередь, приводит к дальнейшему увеличению задержек, числа отброшенных сегментов, повторных передач и т.д.

 

Рис. 6. Пример «узкого места» в сети

Рассмотрим случай, когда «узкое место» находится в самой сети. На рис. 6 изображен низкоскоростной канал между отправителем и получателем, ширина которого пропорциональна скорости передачи данных. Отправитель и получатель подключены к высокоскоростным сетям, но канал между ними создает «узкое место». Каждый посланный сегмент с данными представлен в форме прямоугольника, площадь которого пропорциональна количеству байтов информации в сегменте. Попадая в тонкий канал, сегмент как бы вытягивается в длину, а соответственно, увеличивается время его транспортировки.

Обозначим через P b время прохождения сегмента через определенную точку медленного канала; оно определяется разностью между моментами пересечения этой точки передней и задней границами сегмента. Предположим, что в медленном канале сегменты перемещаются сплошными потоками, т.е. задняя граница одного сегмента вплотную примыкает к передней границе следующего за ним. В данном случае P b определяет и время между прохождениями через фиксированную точку канала передних границ двух последовательных сегментов. При попадании сегментов в высокоскоростной канал это время остается прежним даже с учетом повышения допустимой скорости передачи данных, так как темп поступления сегментов из низкоскоростного канала не меняется. А поскольку в высокоскоростном канале сегмент как бы сокращается, увеличиваясь в ширину, то теперь это время (обозначим его P r ) складывается из времени прохождения самого сегмента и паузы до передней границы следующего сегмента (т.е. P r =P b ). Если получатель подтверждает прием сегментов в момент их поступления, то время между отсылками подтверждающих сегментов (АСК-сегментов) A r на выходе от получателя равно P r . Наконец, время A b (аналог P b для подтверждающих сегментов) будет равно A r , а А s (аналог A r на стороне отправителя) равно Аb.

После попытки работать с высокой скоростью система переходит в устойчивое состояние, в котором скорость отправки сегментов с данными равна скорости поступления подтверждений. Очевидно, что первая скорость будет лимитироваться пропускной способностью самого медленного канала. Можно сказать, что протокол TCP автоматически определяет «узкое место» в сети и регулирует интенсивность потоков. Этот процесс называется самосинхронизацией (self-clocking).

Параметры, влияющие на пропускную способность TCP

Рассмотрим методы определения максимально возможной пропускной способности TCP-соединения, которая зависит от размера окна отправки, задержки и скорости передачи данных. Введем следующие обозначения: W — размер окна в байтах; R — скорость передачи данных (бит/с) по определенному соединению, доступная на стороне отправителя; D — задержка (в секундах) при передаче данных между отправителем и получателем через определенное соединение.

Предположим, отправитель начинает передавать последовательность байтов получателю через установленное соединение. Первый байт достигнет получателя через время, равное D секундам. Такое же время потребуется для получения подтверждения. В течение этого промежутка времени отправитель способен передать 2RD бит, или RD/4 байт. Но отправитель ограничен размером окна в W байт и не может сдвигать окно до получения подтверждения. Только при W≥RD/4 в этом соединении достигается максимально возможная пропускная способность. В противном случае близость фактической пропускной способности к максимальной определяется отношением W к RD/4. Следовательно, нормированная пропускная способность S/Smax может быть выражена как

S/Smax =

{

1, если W≥RD/4,

4W/RD, если W<RD/4.

На рис. 7 представлена зависимость максимальной пропускной способности от произведения RD. Максимальный размер окна может составлять 2 16 -1=65 535 байт (если длина поля «Окно» 16 бит), что достаточно для большинства приложений.

 

Рис. 7. Влияние параметра масштабирования окна
на максимальную пропускную способность

В качестве примера рассмотрим три технологии, применяемые для передачи сегментов ТСР и использующие 16-битное окно. Для 100-метрового канала Gigabit Ethernet произведение RD будет меньше 103 бит. На больших расстояниях, пусть даже при меньших скоростях, скажем при использовании канала T1 (1,544 Мбит/с), произведение RD возрастает и эффективность передачи падает. Тем не менее она остается вполне приемлемой — на уровне 0,8 (см. рис. 7). При дальнейшем увеличении и расстояния, и скорости передачи применение протокола ТСР становится крайне неэффективным: для 155-Мбит/с канала SDH нормированная пропускная способность падает до 0,1. Очевидно, что в данном случае размер окна слишком мал. Необходимо задать другой параметр масштабирования окна, который позволит эффективно использовать пропускную способность канала. Достаточно увеличить этот параметр всего на четыре единицы, и длина окна возрастет до 2 20 -1&ap;10 6 байт.

Анализируя взаимное влияние рассмотренных параметров, можно получить представление о потенциале протокола TCP в плане повышения производительности. При этом следует принять во внимание множество факторов, которые заметно усложняют описанную выше ситуацию.

Во-первых, в большинстве случаев несколько TCP-соединений мультиплексируются через один канал, так что каждое соединение получает часть его доступной пропускной способности. Это приводит к снижению скорости передачи R и, следовательно, эффективности работы протокола.

Во-вторых, множество TCP-соединений будет проходить через несколько маршрутизаторов, и время D окажется равным сумме задержек в отдельных каналах и маршрутизаторах на пути передачи данных. Суммарная задержка в маршрутизаторах часто вносит основной вклад в значение D, особенно при возникновении перегрузок.

В-третьих, значение R в вышеприведенной формуле определяет скорость передачи данных, доступную для соединения только на стороне отправителя. Если она превышает скорость на одном из участков пути от отправителя к получателю, то попытка передачи данных на максимальной скорости приведет к образованию «узкого места», что неизбежно увеличит время D.

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

Для повышения производительности сетей с большими задержками в ОС Microsoft Windows NT 5.0 введен алгоритм масштабирования окна (TCP Receive Window Size Calculation and Window Scaling), описанный в разделе 2.2 документа RFC 1323. При использовании параметра масштабирования окна F число байтов данных, определяемых полем «Окно», становится кратным значению 2F. Максимальное значение F, которое может быть использовано протоколом TCP, равно 14. Следует отметить, что алгоритм масштабирования включается только на время инициирования соединения.

В системе Windows NT размер приемного окна может увеличиваться на величину, кратную максимальному размеру сегмента (Maximum Segment Size, MSS). Значение MSS определяется во время установления соединения. По умолчанию приемное окно задает размер данных 8 Кбайт для Windows NT 4.0 и 16 Кбайт для Windows NT 5.0. Такой размер окна выставляется в реестре операционной системы (параметр ТсрWindowSize — столбец 2 табл. 1). Размер окна, устанавливаемый в сетях Ethernet, позволяет передать 8760 байт информации (8 Кбайт, размещенные в шести сегментах по 1460 байт) для операционной системы Windows NT 4.0 и 17520 байт (16 Кбайт, размещенные в 12 сегментах по 1460 байт) для Windows NT 5.0.

Таблица 1. Параметры реестра Windows NT, регулирующие работу протокола TCP

Параметр

ТсрWindowSize

Tcp1323Opts

Ключ в реестре

Tcpip\Parameters, Tcpip\Parameters\Interface\<interface>

Tcpip\Parameters

Тип записи

REG_DWORD — Number of bytes (количество байтов)

REG_DWORD — Number (флаги)

Возможные значения

0 — 0x3FFFFFFF (десятичное — 1073741823)

0, 1, 2, 3

Значение по умолчанию

17 520 (для сети Ethernet)

3

Для ОС Microsoft Windows NT 5.0 размер окна рассчитывается следующим образом. Первый запрос на установление соединения, посылаемый удаленному абоненту, предлагает установить размер окна, определяющий 16 Кбайт (16 384 байт) данных. После формирования соединения размер приемного окна округляется до объема данных, кратных максимальному размеру сегмента MSS, который был оговорен в процессе установления соединения. Если размер приемного окна определяет объем данных, близкий к четырехкратному значению MSS, то окно выравнивается до значения 4MSS, которое сохранится до тех пор, пока не будет активизирован алгоритм масштабирования окна.

В операционной системе Windows NT 5.0 окно масштабируется автоматически, если параметр ТсрWindowSize реестра установлен в значение, превосходящее 64 Кбайт. Масштабирование окна можно запретить вручную параметром Tcp1323Opts (столбец 3 табл. 1).

Работать с окном, размер которого превышает 64 Кбайт, можно только в том случае, если абонент поддерживает эту опцию. Значение по умолчанию устанавливается как наименьшее из следующих величин: 0xFFFF; значение дополнительного параметра GlobalMaxTcpWindowSize в реестре ОС Windows NT; наибольшее из четырехкратного значения максимального размера данных TCP в сети и значения 16 384, выравненного до кратного размера данных протокола TCP. Значение по умолчанию для сети Ethernet составляет 17 520 байт (в реализации TCP для Windows NT 5.0). Оно может быть немного уменьшено, если соединение установлено с абонентом, который поддерживает алгоритмы SACK и временные метки (time stamp), так как они увеличивают размер заголовка протокола TCP сверх обычного 20-байтного размера, оставляя меньше места для данных.

Размер окна является одновременно и глобальным параметром, и параметром, устанавливаемым отдельно на каждом интерфейсе в зависимости от того, где расположен ключ реестра. Значение для определенного интерфейса перекрывает значение для всей системы.

Параметр Tcp1323Opts может принимать следующие значения: 0 - применение опций RFC 1323 запрещено, 1 — разрешено использовать только масштабирование окна; 2 — разрешено применять только временные метки; 3 — разрешено использовать обе опции.

Управление потоком

Для управления потоком используется не только механизм плавающего окна, но и более гибкая схема передачи данных, их приема и отсылки подтверждений. Управление потоком основывается на лимитной схеме выделения массива данных, разрешенного к отправке.

В соответствии с указанной схемой каждый индивидуальный передаваемый байт имеет собственный номер в последовательности. При отсылке сегмента TCP выставляет в качестве номера в последовательности номер первого из байтов, размещаемых в поле данных этого сегмента. Приемная сторона подтверждает поступление сегмента сообщением, имеющим форму (A = i, W = j). Такая запись означает следующее: А (АСК) подтверждает получение всех байтов, вплоть до номера в последовательности (i - 1); следующие ожидаемые к приему байты имеют номера начиная с i. Кроме того, выдается разрешение на отправку дополнительного окна W (Window) из j данных; соответствующие байты имеют номера в последовательности от i до (i + j - 1).

 

Рис. 8. Принцип управления потоком

Работу этого механизма иллюстрирует рис. 8. Для большей наглядности на нем показан поток данных, идущий только в одном направлении, и предполагается, что в каждом сегменте посылается 200 байт данных. Во время установления соединения номера в последовательностях отправителя и получателя синхронизированы и станция А работает на основе выделенного начального лимита, равного 1400 байт, начиная с номера байта 1001.

Отправив 600 байт в трех сегментах, станция А уменьшает свое окно отсылки до 800 байт (номера с 1601 до 2400). После получения этого сегмента станция В подтверждает получение всех байтов, вплоть до байта с номером 1600 (при этом А=1601), и формирует свое окно приема на 1000 байт. Следовательно, А может посылать байты с номера 1601 по номер 2600 (пять сегментов). Однако к моменту прихода сообщения от станции В на станцию А она уже успела переслать два сегмента, содержащих байты с номерами от 1601 до 2000. Таким образом, на этот момент оставшийся лимит станции А составляет всего 400 байт, или два сегмента. В процессе обмена станция А продвигает левую границу своего окна каждый раз, когда передает данные, а правую — только при получении нового лимита.

На практике обе стороны одновременно задействуют режимы отсылки и приема, поскольку данные могут передаваться в обоих направлениях (режим дуплексной передачи). Механизм выделения лимита достаточно гибок. В качестве примера рассмотрим ситуацию, в которой последним сообщением, посланным станцией В, было (A = i, W = j). Последний байт данных, полученный станцией В, имел номер i - 1. В результате для увеличения лимита до значения k при выполнении условия k > j и отсутствия дополнительных данных станция В формирует сообщение (A = i, W = k), а для подтверждения входящего сегмента, содержащего m байт данных (m < j), без получения дополнительного лимита станция В формирует сообщение (A = i + m, W = j - m).

Следует отметить, что от получателя не требуется немедленного подтверждения приходящих сегментов; обобщенное подтверждение для некоторого их числа может быть сформировано через какое-то время. Тем не менее получатель должен подчиняться определенной политике, регламентирующей количество входных данных, которое он позволяет передавать отправителю. Можно выделить две схемы поведения получателя: «консервативную» и «оптимистическую».

«Консервативная» схема управления потоком основана на том, что лимит выделяется, исходя из фактического значения свободного буферного пространства. Если это правило применить к ситуации, проиллюстрированной рис. 8, то первое лимитирующее сообщение будет говорить о способности станции В разместить в своем буфере 1000 байт, а второе — о возможности разместить 1400 байт. Консервативная схема управления потоком ограничивает пропускную способность логического соединения при возникновении длительных задержек.

Получатель может увеличивать пропускную способность с помощью «оптимистического» выделения лимита на свободное буферное пространство, которого он в данный момент не имеет. Например, если буфер получателя заполнен, но он ожидает, что успеет освободить 1000 байт за время прохождения информации из конца в конец соединения, то он немедленно выделяет лимит на 1000 байт. Если получатель в состоянии поддерживать скорость, заданную отправителем, то такая схема способна повысить пропускную способность без каких-либо отрицательных последствий. Однако в том случае, когда отправитель работает быстрее получателя, некоторые сегменты будут отбрасываться по причине занятости буфера, что повлечет за собой повторную передачу. А поскольку последняя является необходимым атрибутом надежного сетевого сервиса, то «оптимистическое» управление потоком может повысить нагрузку на сеть.

Получатель всегда пытается увеличить приемное окно, если имеет свободное буферное пространство. Отправитель также при малейшей возможности старается расширить окно отсылки на любую допустимую величину. В такой ситуации говорить о стабильном потоке сегментов не приходится. Чтобы уберечь отправителя и получателя от соблазна «втиснуть» в канал лишний сегмент, используется алгоритм предотвращения синдрома «глупого окна» (Silly Window Syndrome, SWS), описанный в RFC 1122. Большой объем данных не отправляется до тех пор, пока получатель не объявит размер окна, достаточный для передачи полного сегмента, либо не будет произведена настройка, не позволяющая увеличивать ширину приемного окна меньше чем на сегмент.

 

Стратегии отправления и приема данных

При отсутствии данных, помеченных флагом PSH, протокол TCP на стороне отправителя имеет возможность самостоятельно назначать время передачи. Когда данные передаются модулю протокола ТСР пользовательским приложением, они записываются в передающий буфер. Протокол TCP может создавать отдельные сегменты для каждой группы данных, поступивших от приложения, либо дожидаться накопления большого объема данных и только после этого формировать и отправлять сегменты. Выбор конкретной политики отправки данных всецело зависит от требований к производительности. Если передачи сегментов происходят редко, но при этом пересылаются большие объемы данных, то накладные расходы, связанные с созданием сегмента и его обработкой, оказываются небольшими. Если же передачи осуществляются часто, а объем транспортируемых данных невелик, то система способна обеспечить быструю реакцию на изменения состояния сети.

Когда отсутствуют данные, помеченные флагом PSH, протокол TCP на стороне получателя также может самостоятельно определять время доставки данных пользовательскому приложению. Так, возможны доставка данных при получении сегментов в их исходной последовательности или занесение данных из нескольких сегментов в буфер приема. Как и в предыдущем случае, реальная схема определяется требованиями к производительности. Если данные приходят редко и имеют большие объемы, то приложение получит их не сразу. Если данные поступают часто и малыми порциями, может возникнуть избыточная и обременительная обработка информации протоколом TCP и приложением.

В том случае, когда сегменты поступают в порядке их отсылки по установленному соединению, протокол TCP помещает данные в буфер получения для доставки пользовательскому приложению. Но вполне возможно, что какие-либо сегменты будут поступать c нарушением первоначального порядка следования. Тогда протокол TCP на приемной стороне сможет принимать только те сегменты, которые приходят в порядке отправления (а остальные просто отбрасывать), либо все сегменты, чьи номера зафиксированы в окне получения (вне зависимости от порядка их поступления).

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

Протокол TCP поддерживает очередь отправленных сегментов, подтверждения о приеме которых еще не поступили. Согласно спецификации протокола сегмент будет передан повторно, если подтверждение не поступит в течение определенного периода. Разные реализации протокола TCP могут поддерживать три стратегии повторной передачи.

«Только первый». Поддерживается один таймер повторной передачи для всей очереди. При получении подтверждения первый сегмент удаляется из очереди повторной передачи и таймер сбрасывается. Если время таймера истекает, повторно передается сегмент из начала очереди и таймер обнуляется.

Пакетная. Также поддерживается один таймер повторной передачи для всей очереди. Когда приходит подтверждение, из очереди повторной передачи удаляются все сегменты и таймер сбрасывается. Если время таймера истекает, повторно передаются все сегменты из очереди и таймер обнуляется.

Индивидуальная. Для каждого сегмента в очереди существует отдельный таймер. При получении подтверждения из очереди повторной передачи удаляется первый сегмент, а соответствующий таймер обнуляется. По истечении времени какого-либо таймера повторно передается только соответствующий сегмент и его таймер сбрасывается.

Первая стратегия повышает эффективность передачи трафика, поскольку повторно передается лишь потерянный сегмент (или тот, чье подтверждение о приеме было потеряно). Однако из-за того, что таймер для второго сегмента в очереди не устанавливается, пока не подтвержден прием первого сегмента, могут возникать некоторые задержки. Индивидуальная стратегия решает эти проблемы ценой более сложной реализации. Использование пакетного режима также снижает вероятность длительных задержек, но способно привести к ненужным повторным передачам.

Реальная эффективность политики повторной передачи зависит от реализуемой схемы приема сегментов на стороне получателя. Если избран подход, при котором принимаются только сегменты, следующие в порядке отправления, то сегменты, поступившие после потерянного, будут отброшены. Такая схема хорошо подходит для пакетной стратегии. Если же получатель принимает все сегменты, независимо от порядка их прибытия, то оптимальными являются стратегии «только первый» и индивидуальная.

При поступлении сегмента протокол TCP на приемной стороне имеет два варианта выбора времени отправки подтверждения.

«Немедленно». Сразу после принятия данных с определенным номером последовательности передается пустой (без данных) сегмент, содержащий соответствующий номер подтверждения.

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

Пример реализации механизма SACK


...

   TCP: Source Port = 0x04DA

   TCP: Destination Port = NETBIOS Session Service

   TCP: Sequence Number = 925104 (0xE1DB0)

   TCP: Acknowledgement Number = 54857341 (0x3450E7D)

{Подтверждение получения данных до номера в последовательности 54857341}

...

   TCP: Options

     TCP: Option Nop = 1 (0x1)

     TCP: Option Nop = 1 (0x1)

     TCP: Timestamps Option

     TCP: Option Nop = 1 (0x1)

     TCP: Option Nop = 1 (0x1)

     TCP: SACK Option

       TCP: Option Type = 0x05

       TCP: Option Length = 10 (0xA)

       TCP: Left Edge of Block = 54858789 (0x3451425)

  TCP: Right Edge of Block = 54861685 (0x3451F75)

{Указание на успешно принятые номера в последовательности данных
 54858789 — 54861685}

...

Алгоритм немедленной отправки подтверждений проще в реализации и позволяет поддерживать полную информированность протокола TCP на отправляющей стороне, что минимизирует ненужные повторные передачи. В то же время его использование приводит к появлению дополнительных пустых сегментов, служащих исключительно для подтверждения успешного приема. Более того, такой подход повышает загруженность сети. Вполне возможна, например, ситуация, в которой протокол ТСР на приемной стороне получает сегмент и немедленно посылает подтверждение, а приложение вдруг расширяет свое приемное окно, инициируя тем самым передачу пустого сегмента для предоставления дополнительного лимита отправляющей стороне.

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

Рассмотрим два расширения протокола TCP, используемых в среде Windows NT.

Выборочное подтверждение (TCP Selective Acknowledgement — SACK, RFC 2018). Это расширение сравнительно недавно одобрил консорциум IETF. Оно позволяет подтверждать прием данных не в порядке их поступления, как это было раньше, а выборочно. Подобный подход имеет два главных преимущества.

Во-первых, повышается эффективность повторной передачи сегментов ТСР благодаря сокращению времени выполнения этой процедуры. Обычно протокол TCP использует алгоритм повторной передачи, опираясь на информацию, которую он получает на основе упорядоченных подтверждений. Такой вариант вполне приемлем, однако в случае его применения для восстановления каждого потерянного сегмента требуется примерно один цикл обращения. SACK же позволяет осуществлять в одном цикле повторную передачу сразу нескольких потерянных сегментов.

Таблица 2. Параметры реестра SackOpts, регулирующие работу протокола TCP
Показатель SackOpts TcpDelAckTicks TcpMaxDupAcks
Ключ в реестре Tcpip\Parameters

Tcpip\Parameters\
Interfaces\<interface>

Tcpip\Parameters
Тип записи REG_DWORD-
Boolean
REG_DWORD-
Number
REG_DWORD-
Number
Границы значений 0, 1 (False, True) 0-6 1-3
Значение по умолчанию 1 (True) 2 (200 мс) 2

Во-вторых, благодаря выборочным подтверждениям протокол TCP точнее оценивает доступную ширину полосы пропускания в условиях нескольких последовательных потерь сегментов и способен обойтись без алгоритма «Медленный старт». SACK играет важную роль в соединениях, в которых используется окно TCP большого размера. Когда работает SACK (а в Windows NT это расширение включено по умолчанию), при потере сегмента или серии сегментов получатель имеет возможность точно проинформировать отправителя о том, какие данные были приняты успешно, и указать на образовавшуюся «прореху» в потоке сегментов. Отправитель может повторно передавать только потерянные данные, а не весь их блок, в состав которого входят и успешно принятые пакеты. Для управления алгоритмом SACK служит параметр SackOpts (столбец 2 табл. 2), определенный в реестре операционной системы Windows NT 5.0.

Врезка иллюстрирует процедуру перехвата сегментов сетевым монитором (Microsoft Network Monitor). В этом примере подтверждено получение данных до номера 54857341, а также данных с номерами от 54858789 до 54861685. Данные с номерами от 54857341 до 54858789 не подтверждены. Таким образом, SACK указывает на то, что данные с номерами от 54857341 до 54858789 были пропущены и отправителю следует повторить их передачу.

Задержанное подтверждение (Delayed Acknowledgement, RFC 1122). В соответствии с этим алгоритмом подтверждения высылаются при условии, что подтверждение приема предыдущего сегмента не отправлялось и после принятия данного сегмента в течение 200 мс не поступил следующий. Значение таймера задержанного подтверждения можно устанавливать с помощью параметра TcpDelAckTicks реестра операционной системы Windows NT 5.0 (столбец 3 табл. 2); впервые он был введен в пакете обновлений Service Pack 4 для версии Windows NT 4.0.

Значения данного параметра могут меняться в диапазоне от 0 до 6, где единица соответствует 100 мс; другими словами, максимальное значение таймера равно 600 мс. Обнуление таймера запрещает использование задержанных подтверждений, что приводит к немедленным отправлениям подтверждений для каждого полученного сегмента.

Таймер повторной передачи

Протокол TCP не формирует явных негативных подтверждений, непосредственно указывающих на нарушение процедуры передачи. Вместо этого он «полагается» исключительно на положительные подтверждения и повторную передачу в тех случаях, когда подтверждение не поступает в течение определенного интервала времени. К повторной передаче сегмента приводит любое из двух событий:

 

  • сегмент был испорчен при передаче, но доставлен получателю. Контрольная сумма, включенная в сегмент, позволяет получателю обнаружить ошибку и отбросить такой сегмент;
  • сегмент просто не поступил к получателю.

В обоих случаях посылающая сторона не знает о том, что передача сегмента оказалась неудачной.

Когда сегмент принимается с ошибками либо не поступает вовсе, подтверждение ACK просто не формируется, что однозначно указывает на необходимость повторной передачи. Для принятия решения о повторной передаче используется таймер, работающий с каждым посланным сегментом. Если время таймера истекает до получения ACK для данного сегмента, отправитель должен выполнить повторную передачу.

Регулируемое время этого таймера является важным параметром протокола TCP. Если его значение будет слишком малым, то заметно участятся ненужные повторные передачи, уменьшающие полезную полосу пропускания сети, что вызовет дополнительные повторные передачи и т. д. При очень большом значении реакция протокола на потерю сегмента станет слишком медленной. Таймер должен быть установлен так, чтобы его значение немного превышало время обращения сегмента (Round Trip Time, RTT). Естественно, эта задержка зависит от множества факторов, влияние которых ощутимо даже при постоянной загрузке сети.

Существуют два способа, позволяющих установить время таймера повторной передачи. В первом случае используется фиксированное значение таймера, величина которого основывается на статистических данных, отражающих обычное поведение распределенной сети (т. е. таймер выставляется с небольшим превышением среднего значения RTT). Понятно, что такая стратегия исключает гибкое реагирование на резкие изменения условий работы сети.

Пример реализации алгоритма «Временная метка»


...

TCP: Timestamps Option

    TCP: Option Type = Timestamps

    TCP: Option Length = 10 (0xA)

    TCP: Timestamp = 2525186 (0x268802)

    TCP: Reply Timestamp = 1823192 (0x1BD1D8)

... 

Второй подход опирается на адаптивную схему, которая также имеет достоинства и недостатки. Предположим, что протокол TCP постоянно отслеживает время получения подтверждений, свидетельствующих о приеме сегментов, и устанавливает значение таймера, основываясь на наблюдаемой задержке. Это значение не может полностью удовлетворять всей совокупности требований к транспортному протоколу по следующим причинам: получение сегмента иногда не подтверждается немедленно (напомним, что привилегия дается задержанным подтверждениям), при повторной передаче сегмента отправитель не знает, относится ли полученный ACK к начальному сегменту или его копии, а кроме того, условия в сети порой меняются внезапно. Эта проблема не имеет исчерпывающего решения: всегда существует некоторая неуверенность в правильности установки значения таймера повторной передачи.

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

Удвоение показаний таймера в алгоритм повторной передачи
Время Отправитель Получатель Протокол Флаги Описание
0.000 10.57.10.32 10.57.9.138 TCP .A.., len: 1460, seq: 8043781, ack: 8153124, win: 8760
0.521 10.57.10.32 10.57.9.138 TCP .A.., len: 1460, seq: 8043781, ack: 8153124, win: 8760
1.001 10.57.10.32 10.57.9.138 TCP .A.., len: 1460, seq: 8043781, ack: 8153124, win: 8760
2.003 10.57.10.32 10.57.9.138 TCP .A.., len: 1460, seq: 8043781, ack: 8153124, win: 8760
4.007 10.57.10.32 10.57.9.138 TCP .A.., len: 1460, seq: 8043781, ack: 8153124, win: 8760
8.130 10.57.10.32 10.57.9.138 TCP .A.., len: 1460, seq: 8043781, ack: 8153124, win: 8760

Рассмотрим один из подходов, который учитывает среднее наблюдаемое время для некоторого количества посланных сегментов. Если это время достаточно точно предсказывает будущие задержки, то полученное значение таймера повторной передачи обеспечит очень хорошую производительность сети. Усредненное время можно определить, используя следующее выражение:

где RTT(i) — наблюдаемое время обращения i-го переданного сегмента, а ARTT(K) — среднее время обращения для первых K сегментов. Для удобства последующего изложения представим приведенное выражение в виде

Следует учесть, что каждый параметр в последней формуле имеет равный вес. Однако, как правило, больший вес, или большая степень доверия, присваивается самым последним замерам, поскольку они точнее всего отражают будущее поведение сети. Общий метод предсказания очередного усредненного значения времени обращения на основе предыдущей серии измерений приведен в документе RFC 793. В его основе лежит выражение

где SRTT(K) — так называемое сглаженное оцененное время обращения (Smoothed Round Trip Time). Нетрудно сравнить это выражение с предыдущим. Используя константу a (0 < a < 1), не зависящую от числа последних наблюдений, можно сформулировать условия, при которых учитываются все последние значения наблюдений, но более ранние наблюдения имеют меньший вес. Эту константу называют фактором сглаживания.

Наименьшее значение константы a придает больший вес самым последним наблюдениям. При a = 0,5 самыми весомыми становятся четыре или пять последних наблюдений, в то время как при a = 0,875 средний вес распределяется между десятью последними наблюдениями (и даже большим их числом). Достоинством использования малого значения константы a является то, что оно позволяет учесть быстрые изменения в наблюдаемых величинах. Недостаток же такого выбора состоит в следующем: при возникновении короткого волнообразного изменения наблюдаемых времен обращения с последующим возвратом к среднему значению происходят резкие изменения вычисляемого усредненного времени обращения.

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

где RTO (Retransmission Time Оut) — контрольное время повторной передачи (его иногда называют тайм-аутом повторной передачи), а D — некоторая константа. Недостаток этого способа состоит в том, что значение D не пропорционально значению SRTT. Для больших значений SRTT величина константы D относительно невелика. В этом случае флуктуации фактического значения RTT будут приводить к ненужным повторным передачам. При малых значениях SRTT величина D, напротив, начинает доминировать и может вызвать ненужные задержки при повторных передачах потерянных сегментов.

В этой связи документ RFC 793 определяет значение таймера, пропорциональное SRTT, со следующими ограничениями:

где UBOUND и LBOUND — фиксированные верхняя и нижняя границы значения таймера, а b — константа, называемая фактором изменения задержки. Документ RFC 793 не рекомендует применять фиксированные значения, в нем приводятся следующие диапазоны изменений параметров: a — между 0,8 и 0,9; b— между 1,3 и 2,0.

Временные метки

Для соединений, в которых используются окна большого размера, применяется алгоритм временных меток (TCP Timestamps), описанный в документе RFC 1323. Временные метки помогают проводить точное измерение времени обращения RTT для последующей корректировки значения таймера повторной передачи.

В упомянутом алгоритме определяются два дополнительных поля: Timestamp Value и Timestamp Echo Reply. Первое может быть включено протоколом TCP в любой отправляемый сегмент. При подтверждении успешного приема этого сегмента получатель включает в ответный сегмент поле Timestamp Echo Reply с тем же значением, что было в Timestamp Value. Это позволяет протоколу TCP осуществлять постоянный мониторинг времени обращения сегментов.

Во врезке приведен фрагмент процедуры перехвата сегментов сетевым монитором с полями алгоритма временных меток. В операционной системе Windows NT 5.0 использование временных меток разрешено по умолчанию.

В ОС Windows NT версий 4 и 5 число повторных передач устанавливается алгоритмом, определяющим поведение протокола TCP. Протокол TCP запускает таймер в момент передачи сегмента протоколу IP. Для новых соединений таймер инициируется со значением 3 с. При каждой повторной отправке сегмента начальное значение таймера увеличивается на величину, указанную в параметре TcpMaxConnect Retransmissions реестра ОС Windows NT (значение по умолчанию для NT 5.0 равно двум, а для NT 4.0 — трем). Для действующих соединений управление числом попыток повторной передачи осуществляется при помощи параметра TcpMaxDataRetransmissions (значение по умолчанию равно пяти), описанного в реестре Windows NT.

В целях оптимизации параметров соединения таймер повторной передачи может корректироваться «на лету» с использованием величины SRTT. В результате протокол TCP самонастраивается с учетом задержек на данном соединении и других факторов работы сети. Соединения TCP, устанавливаемые в каналах с большой задержкой, требуют большего начального значения таймера повторной передачи, чем соединения в быстрых каналах связи.

Приведем пример работы сетевого монитора, использующего алгоритм повторной передачи в сети Ethernet (см. врезку). В середине процесса передачи большого файла по протоколу FTP получатель был отключен от сети. Так как значение SRTT для данного соединения крайне мало, то первая повторная передача произойдет примерно через 0,5 с. Затем значение таймера будет удваиваться после каждой повторной передачи. Если после пяти повторных передач подтверждения не поступают, то соединение разрывается.

Контрольное время RTO, которое используется отправителем для повторной передачи потерянного сегмента, на практике может заметно превосходить реальное время обращения RTT. На величину этого превышения влияют следующие причины.

 

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

Понятно, что в случае завышенного RTO и потери сегментов протокол TCP становится инертным при осуществлении повторной передачи. Если протокол на стороне получателя использует правило «прием в порядке отправления», это может привести к потере множества сегментов. Даже в более благоприятном случае, когда получатель принимает все указанные в окне отправления сегменты, медленная повторная передача также способна вызвать проблемы.

Поясним сказанное на примере. Предположим, что станция А передала последовательность сегментов, первый из которых был потерян. До тех пор, пока окно отправления станции А не обнулится и RTO не закончится, эта станция будет продолжать передавать сегменты, не дожидаясь получения подтверждений на ранее отосланные. Станция Б получила все сегменты за исключением первого. Ей надлежит помещать все принимаемые сегменты в буфер, пока не поступит копия потерянного сегмента. Более того, станция Б не может отправить данные приложению и тем самым очистить свой буфер до поступления этой копии. Если повторная передача потерянного сегмента по каким-то причинам сильно задержится, то после заполнения буфера станция Б начнет отбрасывать новые входящие сегменты.

Чтобы уменьшить негативные последствия описанной выше ситуации, был предложен алгоритм быстрой повторной передачи (Fast Retransmission), который повышает производительность сети при неоптимальном выборе RTO. Этот алгоритм определяет следующие правила работы протокола TCP. Когда сегмент поступает на приемную сторону не в порядке отправления, немедленно формируются подтверждения о приеме последнего сегмента, пришедшего в порядке отправления, и всех последующих. Подтверждения будут отсылаться до тех пор, пока не поступит копия пропущенного сегмента. После этого протокол перейдет в режим отсылки накопленных подтверждений о приеме всех сегментов, полученных в порядке отправления.

Когда отправитель получает двойное подтверждение о получении одного из сегментов (поступившего последним в порядке отправления), он способен интерпретировать это событие двояко: либо нарушена последовательность получения (по разным причинам), либо произошла потеря сегмента. В первом случае сегмент все же может поступить к получателю, и без повторной передачи удастся обойтись. Во втором случае двойное подтверждение указывает на то, что, возможно, понадобится отослать копию сегмента. Для окончательного принятия решения об отсылке копии отправитель должен получить три дополнительных подтверждения о получении одного и того же сегмента (т. е. всего четыре подтверждения). В этом случае, не дожидаясь срабатывания таймера повторной передачи, он передает в сеть копию потерянного сегмента.

 

Рис.9 Быстрая повторная передача

На рис. 9 показано, как реализуется алгоритм быстрой повторной передачи. Станция А отсылает последовательность сегментов с 200 байтами данных в каждом. Предположим, что сегмент 1201 был потерян, но станция А не реагирует на это событие до истечения времени RTO. Она будет посылать новые сегменты до тех пор, пока не закроется ее окно отсылки. Станция Б получает сегмент 1001 (с байтами от 1001 до 1200) и высылает подтверждение с номером 1201. Затем к ней поступает сегмент 1401 (байты от 1401 до 1600). Поскольку он нарушает последовательность отсылки, станция Б повторяет отправку подтверждения с номером 1201 и затем станет высылать подтверждение с этим номером при поступлении каждого нового сегмента. Процесс будет продолжаться до получения копии сегмента 1201. За время, прошедшее между отправкой сегмента 1201 и получением четвертого подтверждения с тем же номером, станция А успеет отправить семь сегментов. Получив четвертое подтверждение с номером 1201, она немедленно повторит последовательность сегментов, начиная с данного номера.

По умолчанию в Windows NT 5.0 сегмент посылается повторно, если поступают три подтверждения с одинаковым номером, который в последовательности отстает от текущего. Управление осуществляется с помощью параметра TcpMaxDupAcks, описанного в реестре операционной системы (столбец 4 табл. 2). Этот параметр определяет число двойных подтверждений с одним номером, которые должны быть получены, прежде чем начнет выполняться алгоритм быстрой повторной передачи.

Контроль за перегрузками

В сетях IP контроль за перегрузками реализовать достаточно сложно.

Во-первых, протокол IP не ориентирован на установление соединения. Он не обеспечивает обнаружение состояний перегрузки, поэтому не может быть использован для контроля за ними.

Во-вторых, хотя протокол TCP и осуществляет управление потоком, он обнаруживает перегрузку в сети лишь по косвенным признакам. Более того, поскольку задержки в распределенных сетях постоянно изменяются и могут быть очень большими, то информация, полученная на основании косвенных признаков, не является достоверной.

В-третьих, не существует распределенного алгоритма для связывания различных реализаций протокола TCP: ПО протоколов TCP, запущенное на разных компьютерах, не способно взаимодействовать для поддержания определенных характеристик общего потока. На практике приложения ведут себя весьма «эгоистично» по отношению к свободным ресурсам канала.

Сообщение «Подавление источника» (Source Quench) протокола ICMP можно рассматривать как грубый инструмент сдерживания потоков, генерируемых отправителем, но его нельзя причислить к эффективным методам контроля за перегрузками. На протокол RSVP удается возложить функции контроля за перегрузками, однако его широкого распространения стоит ожидать только в будущем (пусть и не очень отдаленном).

Протокол TCP может влиять на загрузку сети, управляя потоками данных с помощью рассмотренных выше методов, но без принятия специальных мер ему сложно поддерживать загрузку каналов связи на оптимальном уровне. Практически во всех современных реализациях протокола применяются алгоритмы, предотвращающие возникновение перегрузок в сети. К ним относятся алгоритмы «Медленный старт» (Slow Start) и предотвращения перегрузок (Congestion Avoidance, RFC 1122), динамическое изменение окна при перегрузке, быстрая повторная передача и быстрое восстановление.

«Медленный старт»

Казалось бы, чем больший размер окна определен отправителем, тем больше сегментов он успеет отослать до момента получения очередного подтверждения. Но на практике все происходит совсем иначе. В установившемся режиме передачи данных скорость отправки сегментов регулируется за счет автосинхронизации протокола. Гораздо сложнее выбрать такие начальную скорость передачи данных (сразу же после создания соединения) и алгоритм ее повышения, которые позволяют в одночасье не заполнить своими сегментами весь канал связи. Решить задачу можно двумя способами.

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

Второй способ заключается в использовании сразу после формирования соединения минимального размера окна отсылки, который ни при каких обстоятельствах не вызовет перегрузку сети. «Изюминка» этого подхода — наращивание размера окна отсылки с помощью алгоритма «Медленный старт».

В протоколе TCP применяется новое окно, окно перегрузки, размер которого измеряется не в байтах, а в количестве сегментов. В любой момент скорость передачи данных протоколом TCP определяется следующим образом:


AWND = min[CREDIT, CWND].

Здесь AWND — разрешенный размер окна передачи в сегментах, иначе говоря — число сегментов, которое протоколу TCP разрешено отправить в данный момент без получения подтверждений об их успешном приеме; CWND — размер окна перегрузки в сегментах, используемого протоколом TCP в начальный период работы и позволяющего снизить скорость передачи данных при возникновении перегрузки; CREDIT — неиспользуемый на данный момент лимит отсылки сегментов, который был выдан в самых последних подтверждениях.

При создании нового соединения TCP устанавливает окно перегрузки CWND равным единице. Это означает, что отправитель может послать только один сегмент и должен дождаться подтверждения о его успешном приеме, прежде чем отправить следующий сегмент. Каждый раз, когда поступает подтверждение, значение окна CWND увеличивается на единицу. Так происходит до тех пор, пока размер данного окна не достигнет максимального значения.

Поскольку отправитель расширяет свое окно отсылки только по мере прибытия подтверждений, процедура «Медленный старт» гарантирует, что в распределенной сети, даже если она работает на пределе своих возможностей, не окажется слишком много сегментов. Таким образом, протокол ТСР учитывает текущую загруженность канала связи.

Описанный алгоритм правильнее было бы назвать «Экспоненциальным стартом», так как на самом деле размер окна CWND увеличивается в соответствии с показательной функцией. Получив первое подтверждение, протокол TCP увеличивает размер окна CWND в два раза и посылает сразу два сегмента. После этого окно CWND увеличивается на единицу для каждого приходящего подтверждения. Следовательно, получив подтверждение о получении двух последних отосланных сегментов, отправитель может послать уже четыре сегмента, а дождавшись подтверждений об их приеме, отправить восемь сегментов и т. д.

Рис.10 Динамическое изменение окна перегрузки

Сказанное иллюстрирует рис. 10. В этом примере станция А посылает сегмент размером 100 байт и по истечении приблизительно четырехкратного времени обращения RTT получает возможность заполнить канал связи непрерывным потоком своих сегментов.

Алгоритм «Медленный старт» достаточно эффективен при установлении соединения. Он позволяет протоколу TCP на стороне отправителя быстро определить оптимальный размер окна для данного соединения. Но что делать, если, несмотря на принятые меры, перегрузка все-таки возникла?

Предположим, что устанавливается соединение с «Медленным стартом» и прежде чем увеличивающийся размер окна перегрузки CWND достигает лимита, выделенного отправителю другой стороной, происходит потеря сегмента. Этот факт может свидетельствовать о перегруженности сети, однако данных, позволяющих оценить серьезность возникшей ситуации, практически не существует. А раз так, то самым очевидным решением будет сброс размера окна перегрузки CWND до первоначального единичного значения и повторный запуск процедуры «Медленный старт».

Подобная стратегия может показаться вполне приемлемой, но, к сожалению, только на первый взгляд. Давно не требует доказательств тот факт, что перегрузить сеть легко, но восстановить ее нормальное функционирование сложно. Иными словами, после возникновения перегрузки для восстановления рабочих параметров сети могут потребоваться достаточно длительное время и значительные усилия администратора и участников сетевого обмена. Следовательно, при экспоненциальном росте размера окна перегрузки CWND (после восстановления единичного значения) его величина способна довольно быстро снова достичь максимума, хотя к этому времени нормальные параметры сети еще не будут восстановлены. Поэтому повторный «Медленный старт» не облегчит, а, наоборот, усложнит процесс восстановления.

Рис.11 «Медленный старт» с линейным ростом окна перегрузки: а — заканчивающийся потерей сегмента; б — с предотвращением перегрузки

Для разрешения указанной проблемы был предложен алгоритм «Медленный старт» с линейным ростом размера окна перегрузки CWND. В случае его применения при возникновении перегрузки в сети выполняются следующие действия.

 

  • Значение переменной SSTHREST (граница «Медленного старта») устанавливается равным половине текущего размера окна перегрузки: SSTHREST = CWND/2.
  • Размер окна перегрузки CWND определяется равным единице, и процедура «Медленного старта» выполняется до тех пор, пока размер окна CWND не сравняется с установленным значением переменной SSTHREST (шаг 1). В этой фазе размер окна CWND будет увеличиваться на единицу после получения подтверждения о приеме каждого посланного сегмента.
  • Если размер окна CWND превысил значение переменной SSTHREST, то его следует увеличивать на единицу каждый раз по истечении времени обращения сегмента RTT.

Рис.12 Временная диаграмма для алгоритмов «Медленный старт» и предотвращения перегрузок

Модифицированный вариант процедуры «Медленный старт» показан на рис. 11. При этом на рис. 11,а отображена динамика роста размера окна перегрузки, аналогичная представленной на рис. 10, только в данном случае последний сегмент потерян. Рис. 11,б иллюстрирует реакцию протокола на потерю сегмента. Значение переменной SSTHREST устанавливается равным восьми. До тех пор, пока размер окна перегрузки не достигнет этой величины, оно растет по экспоненте, а после прохождения указанного рубежа увеличивается линейно.

На рис. 12 окно CWND шириной восемь сегментов задает граничное значение. И если для достижения тайм-аута здесь понадобилось четыре времени обращения RTT, то для повторного вхождения в этот режим потребуется уже одиннадцатикратное время RTT.

* * *

Мы рассмотрели далеко не все алгоритмы и технологии, позволяющие оптимизировать протокол ТСР. Тем не менее автор надеется, что использование даже указанных методов будет способствовать более уверенной работе сетевых администраторов.


Новости все
04.10.17
В Google Play вирус

В Google Play обнаружили вирус, который воровал пароли от мобильных банков

05.09.17
США отключат любой компьютер в мире

В процессорах Intel тайный модуль, при активизации которого США одним движением могут отключить любой компьютер в мире.

17.03.16
Жесткий диск WD80EFZX ёмкостью 8 Тбайт от Western Digital
07.03.16
Материнская плата A68M-ITX от компании ASRock
03.03.16
4K-монитор ASUS MX27UQ с Adaptive-Sync с диагональю 27-дюймов
Информация
Опрос:
Смартфон какого бренда Вы предпочтете?

HTC
SONY
LG
SAMSUNG
NOKIA
ALCATEL
PHILIPS
APPLE
EXPLAY
ASUS
HUAWEI
ZTE
SENSEIT
SONIM
ACER
BLACKBERRY
LENOVO
SONYERICSSON
TEXET
DIGMA
FLY



 

Закрыть