Причиной написания этой статьи стала лень, которая, как известно, является двигателем прогресса и свидетельницей рождения вещей, невероятно облегчающих жизнь.
В моем случае лень было в тысячный раз объяснять клиенту, почему он арендовал канал «точка-точка», а в договоре черным по белому написано Ethernet 1 Гбит/с, но как бы он ни измерял, получается выходит немного меньше.
Где остальное? Почему дефицит? Куда пропал интернет из провода? А может, его совсем обманули? Что ж, будем искать, а заодно напишем заметку, которую не стыдно будет показать тысячному клиенту, у которого будет задержка по скорости.
Важный
Если вы сетевой инженер, не читайте эту статью.Она заденет все ваши чувства, потому что.
написана самым простым и доступным языком с множеством пропусков.
Рассказ об окнах.
Мир за окнами Итак, чтобы понять, где же скорость, нам придется понять, как работает TCP с точки зрения обеспечения надежности соединения.
Как мы все знаем, у TCP есть трюк на крайний случай: когда все уловки по доставке кадра получателю не работают, он просто повторно отправляет поврежденный или потерянный кадр.
Вот как это выглядит в самом простом случае:
- Кадр отправляется передатчиком.
На передатчике включается таймер, в течение которого от получателя должно быть получено ACK-подтверждение об успешном получении кадра или явное указание на то, что кадр был поврежден/потерян в пути - NACK
- Если ACK не получен после истечения таймера, пакет отправляется снова.
- Если приходит NACK, источник повторно отправляет кадр.
- И если ACK получен, источник отправляет следующий кадр.
Этот алгоритм называется методом простоя источника, что сразу заставляет понять его главный недостаток: катастрофически неэффективное использование канала связи.
Технически ничто не мешает передатчику отправить второй сразу после отправки первого кадра, но мы заставляем его ждать прихода ACK/NACK или истечения таймера.
Поэтому важно понимать, что процессы отправки и получения ACK могут происходить независимо друг от друга.
На этой идее родился метод скользящего окна.
Окно первое.
Скользящий.
Теоретический.
После осознания недостатков предыдущего метода в голову приходит идея позволить источнику передавать пакеты с максимально возможной для него скоростью, не дожидаясь подтверждения от получателя.
Но не бесконечное их количество, а ограниченное неким буфером, называемым окном, и его размер указывает на количество кадров, которые разрешено передавать без ожидания подтверждений.
Вернёмся к картинкам:
Для наглядности рассмотрим окно размером K кадров, в котором в определенный момент времени находятся пакеты (1.N), т.е.
мы отправили кучу кадров, каждый кадр, насколько это возможно, дошел до получателя, который их обработал и отправил подтверждение по каждому.
Теперь усложняем ситуацию, включая время.
На момент поступления ACK на первый кадр последний еще даже не отправлен, но так как мы знаем об успешности доставки, то можем добавить в окно следующий по порядку кадр, т.е.
окно смещается и теперь включает кадры 2.N+1. Когда ACK приходит во втором кадре, окно снова смещается: 3.N+2. И так далее.
Получается, что окно словно «скользит» по потоку пакетов.
Или пакеты через него, кому как удобнее представить.
Таким образом, все кадры глобально делятся на три типа:
- Прошлые.
Отправлены, получены подтверждения
- Суровое настоящее.
Состоит из отправленных кадров, но без полученных подтверждений и тех, которые уже есть в окне, но стоят в очереди на отправку.
- Светлое будущее.
Кадры в очереди, чтобы попасть в окно.
И как это влияет на скорость связи? - ты спрашиваешь.
Как видно из графика, необходимым условием максимального использования канала связи является регулярное получение подтверждений внутри окна.
ACK не обязательно должны приходить в четком порядке, главное, чтобы ACK для первого кадра в окне пришел до отправки последнего кадра, иначе сработает таймер неответа, кадр будет отправлен еще раз, и движение окна прекратится.
Также стоит отметить, что в большинстве реализаций алгоритма скользящего окна подтверждения приходят не для каждого пакета, а для всего полученного пакета сразу (так называемое Selective Ack).
Это позволяет еще больше повысить эффективность использования канала за счет уменьшения объема служебной информации.
Итак, что мы имеем в итоге? Какие параметры оказывают существенное влияние на эффективность передачи данных между двумя точками? Их два:
- Размер окна, в зависимости от того, что меньше из окна, объявленного получателем (размер его буфера), или CWND — размер, определенный отправителем на основе RTT.
- Сам RTT: время прохождения туда и обратно, равное времени, затраченному на отправку сигнала, плюс время, необходимое для подтверждения приема.
Давайте представим, что у нас есть сверхнадежная сеть, в которой пакеты почти никогда не теряются и не ломаются.
В такой сети нам выгодно иметь окно максимально возможного размера, что позволит минимизировать паузы между отправкой кадров.
В плохой сети ситуация обратная — при частых потерях и большом количестве битых пакетов нам важно доставить каждый из них в целости и сохранности, поэтому уменьшаем окно, чтобы трафика терялось как можно меньше.
и мы избегаем фатальных повторных передач.
В этом случае придется пожертвовать скоростью.
А как мы все знаем, реальность представляет собой смесь двух крайних случаев, поэтому в реальной сети размер окна является переменным.
При этом он может быть изменен как в одностороннем порядке с любой из сторон, так и по соглашению сторон.
Промежуточное резюме.
Как мы видим, даже без привязки к конкретным протоколам технически крайне сложно задействовать канал на 100%, поскольку хотим мы этого или нет, но даже в лабораторных условиях будут минимальные задержки между кадрами, что не позволит нам достичь желанного 100% использования полосы пропускания.
А что уж говорить о реальных сетях? Во второй части мы рассмотрим одну из реализаций на примере TCP.
Окно второе.
Реализация в TCP Что такого особенного в TSR? Основанный на ненадежных IP-дейтаграммах, он обеспечивает надежную доставку сообщений.
При установлении логического соединения модули TCP обмениваются друг с другом следующими параметрами:
- Размер буфера получателя — это верхний предел размера окна.
- Начальный порядковый номер байта, с которого начнется отсчет потока данных в рамках этого сеанса.
Звучит громоздко, но написать проще простого.
Итак, протокол TCP является дуплексным, а это значит, что каждая сторона в любой момент времени выступает и отправителем, и получателем.
Следовательно, на каждой стороне должен быть буфер для приема сегментов и буфер для еще не отправленных сегментов.
Но кроме того, должен быть еще и буфер для копий уже отправленных сегментов, для которых еще не получено подтверждение о получении.
Кстати, это приводит к особенности, которую многие упускают: условия сети могут быть разными в двух направлениях, а это означает разные размеры окон и разную пропускную способность.
В такой ситуации танец основывается на возможностях получателя.
Когда соединение установлено, обе стороны отправляют друг другу окна приема.
Получатель помнит его размер и понимает, сколько байт можно отправить, не дожидаясь подтверждения.
Тогда активируются механизмы, описанные в первой главе.
Отправка сегментов, ожидание подтверждения, повторная отправка при необходимости и т. д. Важным отличием от теоретических исследований является сочетание различных методик.
Например, прием нескольких пришедших по порядку сегментов происходит автоматически, прерываясь только в случае потери порядка поступления.
Это одна из функций буфера приемника — восстанавливать порядок сегментов.
И тогда, если в потоке будет обнаружен обрыв, модуль TCP сможет повторить запрос на потерянный сегмент. Несколько слов о буфере копирования на отправителе.
Во всех сегментах этого буфера работает таймер.
Если соответствующий ACK поступает в течение таймера, сегмент удаляется.
Если нет, то оно отправляется еще раз.
Возможно, что по таймеру сегмент будет отправлен еще раз до того, как придет ACK, но в этом случае повторный сегмент будет просто отброшен получателем.
И от этого таймаута ожидания зависит производительность TSR. Если он слишком короткий, будут повторяться избыточные пакеты.
Слишком долго — получим даунтайм из-за ожидания несуществующих ACK. Фактически TCP определяет размер таймаута с помощью сложного адаптивного алгоритма, который учитывает скорость, надежность, длину линии и многие другие факторы.
Но в общих чертах это так:
- При отправке каждого сегмента измеряется время до прибытия ACK.
- Полученные значения усредняются с увеличением весовых коэффициентов от прошлого к будущему.
Это позволяет новым данным оказывать большее влияние на конечный результат.
- Затем вычисляется среднее значение от усреднения на предыдущем шаге и получается значение таймаута.
Но если разброс значений очень велик, то учитывается и дисперсия.
Окна на разных концах соединения обычно имеют разные размеры.
В мире торжествующих клиент-серверных технологий нельзя ожидать, что клиент будет готов работать с окном того же размера, с которым может справиться сервер.
Точно так же ее размер может динамически меняться в зависимости от состояния сети, но здесь неправильный выбор уже подразумевает «двойную» ответственность.
Если будет получено больше данных, чем сможет обработать TCP-модуль, они будут отброшены, на источнике сработает таймер, он отправит данные повторно, они снова не поместятся в размер окна и т. д. С другой стороны, установка слишком маленького окна приведет к тому, что канал будет использоваться со скоростью, равной скорости передачи одного сегмента.
Поэтому разработчики TCP предложили схему, при которой при установлении соединения размер окна задается сравнительно большим и в случае проблем начинает уменьшаться вдвое за шаг.
Это действительно выглядит странно, поэтому были созданы реализации TCP, повторяющие привычную нам логику: начать с маленького окна и, если сеть справляется, то начать его увеличивать.
Но на размер окна приема может влиять не только принимающая сторона, но и отправитель данных.
Если мы видим, что ACK регулярно приходят позже таймеров, что сегменты приходится часто пересылать, то источник может установить собственное значение окна приема и будет применяться правило наименьшего — будет принято наименьшее значение, независимо от того, кто его назначил.
.
Осталось рассмотреть еще один сценарий, а именно перегрузку TCP-соединения.
Такое состояние сети характеризуется тем, что на промежуточных и конечных узлах возникают очереди пакетов.
В этом случае у получателя есть два варианта:
- Уменьшите размер окна.
- Полностью отказаться от приема, установив размер окна в ноль.
Существует специальный индикатор срочности, который заставляет порт принять сегмент данных, даже если это означает очистку существующего буфера.
А отправитель, получив нулевой размер окна, не теряет надежды и периодически отправляет получателю запросы на управление и, если он уже готов принять новые данные, то в ответ он получит новый, ненулевой размер окна.
.
Общий
Капитан предлагает — если одна TCP-сессия в принципе не может обеспечить 100% загрузку канала, то используйте две.Если речь идет о клиенте, который арендовал канал «точка-точка» и установил в нем GRE-туннель, то пусть устанавливает второй.
Чтобы они не дрались за полосу, сворачиваем в первый важный поток, во второй - всякую ерунду, и жутко снижаем его скорость.
Этого как раз достаточно, чтобы выделить остатки полоски, которые первый сеанс взять чисто технически невозможно.
Теги: #Сетевые технологии #ИТ-инфраструктура #Системное администрирование #tcp #сети для самых маленьких #сети для самых маленьких #linkmeup #tcp window #tcp window #где гигабит #Лебовски?
-
Sql Server 2008 Задерживается
19 Oct, 24 -
Потом О Самолетах И Правилах
19 Oct, 24 -
Список Все В Календаре Google
19 Oct, 24 -
Наш Мозг Как Примитивная Нейронная Сеть
19 Oct, 24 -
Вы Участвовали В Часе Земли?
19 Oct, 24 -
Вопросы Владимиру Долгову
19 Oct, 24