Шейпинг трафика что это
Основы шейпинга в MikroTik RouterOS
Шейпинг — это технология, позволяющая ограничивать скорость и качество доступа в интернет.
Шейпер — это программа, осуществляющая ограничение скорости. Шейпер работает по алгоритму, который управляет очередностью пакетов данных и ограничивает скорость путем отбрасывания пакетов, не удовлетворяющих определенным условиям.
HTB Шейпер
В различных операционных системах шейперы реализованы по разному.
В Windows шейперы представляют собой программные пакеты, в основном платные и практически не настраиваемые.
В Linux гораздо больше простора для создания шейперов, поскольку операции с сетевыми пакетами встроены непосредственно в ядро операционной системы. За счет этого достигается лучшее быстродействие и надежность.
В Linux шейпер создается путем добавления требуемой очереди непосредственно к сетевому интерфейсу. Этот элемент называется qdisc (Queueing Discipline — Дисциплина организации очереди).
Дисциплина организации очереди (qdisc) — это алгоритм, который захватывает пакеты и определяет, в каком порядке и каким образом они будут двигаться. Задавая разные qdisc на интерфейсе, можно применять разные алгоритмы управления трафиком.
Дисциплины организации очереди делятся на два вида:
Управление пропускной способностью в Mikrotik RouterOS основано на дисциплине HTB (Hierarchical Token Bucket). Она одна из самых удобных, простых и надежных дисциплин для организации шейпера.
В Mikrotik RouterOS есть следующие основные возможности по управлению трафиком:
HTB позволяет организовать древовидную иерархию из очередей и направлять в них трафик при помощи системы фильтров. Для понимания принципа работы HTB рассмотрим следующую аналогию:
Есть дорога, по которой ходят трамвай, троллейбус и такси. Согласно ПДД скорости каждого из транспортных средств строго определены — у трамвая это 40 км/ч, у троллейбуса — 70 км/ч и у такси — 100 км/ч. У каждого из транспортов на дороге своя полоса. У трамвая — рельсы, у троллейбуса — дорога под проводами. Ну а у такси вся остальная дорога. Пассажиры выбирают транспорт в соответствии со своим достатком или желанием. Те, кто побогаче — едут на такси, самые бедные — на трамвае, ну а средний класс — на троллейбусе.
HTB состоит из следующих элементов:
Таким образом, трафик сначала отфильтровывается в соответствующую очередь, а затем движется по ней (точнее выдается из нее) со скоростью, определённой в классе. На практике это работает именно в таком порядке. Хотя первым делом пакет проходит фильтр.
Из классов строится иерархия HTB. Иерархия нужна для сложного распределения скорости пакетов в классах. Нижестоящие классы получают разрешенную скорость от вышестоящих.
Пример иерархии классов HTB можно увидеть на рисунке ниже. Иерархия представлена в виде некого гибридного дерева разделенного уровнями Level0, Level1, конечными вершинами которого являются клиенты или листья Leaf1, Leaf2. Классы, которые не имеют дочерних, будем называть клиентами или листьями. Обычно они находятся на нулевом уровне иерархии и первыми захватывают относящийся к ним трафик, передавая его родителям. Два или более класса, имеющие одного прямого родителя находятся на одном уровне и подсоединены к одной локальной выходной очереди.
Схематическое изображение структуры HTB.
В иерархию классов из файервола (Filter) поступают пакеты с данными. В зависимости от приоритета, параметров классов и загрузки канала они попадают или в локальные очереди (Self Feed), или передаются в очереди родительских классов (Inner Feed).
Любой класс HTB обладает следующими параметрами:
Класс может находиться в одном из трех состояний:
Рассмотрим несколько примеров работы HTB.
Выполните в консоли New Terminal следующие команды:
# Создаем основной класс ClassA с ограничением скорости 2 Мбит/с.
queue tree add name=ClassA parent=Local max-limit=2048000
# Создаем класс ClassB с ограничением скорости 1 Мбит/с. Для ClassB класс ClassA будет родительским.
queue tree add name=ClassB parent=ClassA max-limit=1024000
# Добавляем лист Leaf1 с родительским классом ClassA, ограничением скорости 2 Мбит/с, гарантированной скоростью 1 Мбит/с и приоритетом 8.
queue tree add name=Leaf1 parent=ClassA max-limit=2048000 limit-at=1024000 packet-mark=packet_mark1 priority=8
# Добавляем лист Leaf2 с родительским классом ClassB, ограничением скорости 1 Мбит/с, гарантированной скоростью 256 Кбит/с и приоритетом 7. Данные пакеты будут промаркированы как packet_mark2.
queue tree add name=Leaf2 parent=ClassB max-limit=1024000 limit-at=256000 priority=7 packet-mark=packet_mark2
# Добавляем лист Leaf3 с родительским классом ClassB, ограничением скорости 1 Мбит/с, гарантированной скоростью 768 Кбит/с и приоритетом 8. Данные пакеты будут промаркированы как packet_mark3.
queue tree add name=Leaf3 parent=ClassB max-limit=1024000 limit-at=768000 priority=8 packet-mark=packet_mark3
1. Рассмотрим первый случай, когда листья Leaf1 и Leaf2 передают данные со скоростью меньше, чем указано в параметре limit-at, а Leaf3 не работает.
Как видим, пакеты с данными от leaf1 и leaf2 (клиенты) не передаются в родительские классы, а выстраиваются в локальную очередь в соответствии со своими приоритетами.
2. Теперь посмотрим что будет, в случае если клиент leaf2 будет передавать данные со скоростью больше limit-at, но меньше max-limit указанных в его параметрах и меньше limit-at в параметрах ClassB, к которому он прикреплен. Одновременно с ним leaf1 будет передавать данные со скоростью не превышающей limit-at.
В данном случае получается интересная ситуация: клиент leaf1 будет иметь больший приоритет, чем leaf2, хотя в параметрах последнего указан больший приоритет. Это связано с тем, что передавая данные со скоростью более limit-at leaf2 подключился к родительскому классу, имеющему приоритет 8. При этом существует правило, что на нижних уровнях приоритет пакетов при одинаковых условиях больше, чем на верхних.
3. Рассмотрим следующий пример: скорости передачи данных для leaf1 превысила допустимое max-limit, клиент leaf2 передает данные на скорости больше limit-at и меньше max-limit, клиент leaf3 работает на скорости меньше limit-at.
Это весьма интересный случай. В данной ситуации видно, что ClassA перегружен данными из Leaf1, поэтому ClassB не получит разрешения на передачу. В результате работоспособным окажется только клиент leaf3, подключенный в локальную очередь на нулевом уровне.
4. Теперь рассмотрим пример, когда данные будут одновременно передавать leaf1, leaf2, leaf3, ClassB будет желтым, а ClassA зеленым.
В результате этого на втором уровне leaf2 попадет в очередь первым (так как имеет больший приоритет), а leaf1 и leaf3 подвергнутся случайному выбору для определения порядка следования.
Алгоритм работы HTB весьма логичен. Он был принят многими производителями программного и аппаратного обеспечения за свою гибкость, надежность и отсутствие свойственных его предшественникам недостатков. Благодаря огромной универсальности с помощью него можно строить практически любые возможные иерархии правил, в точности разграничивая и давая возможность управлять потоками данных на достаточно низком уровне.
Пиковая скорость Burst
Пиковая скорость Burst применяется для того, чтобы выдать клиенту максимальную скорость на определенный промежуток времени.
Например, вам нужно ускорить загрузку страниц, и при этом ограничить скорость на закачку файлов. Или нужно изредка передавать и принимать данные, но делать это с максимальной скоростью.
Пиковая скорость обладает следующими параметрами:
Момент, когда клиенту или классу нужно выдать максимальную скорость, определяется следующим образом. Раз в 1/16 времени burst-time вычисляется загрузка канала на указанное число секунд. Если средняя загрузка составила менее burst-threshold, то клиенту или классу выделяется указанная в burst-limit скорость до тех пор, пока она не превысит burst-threshold. После этого действует ограничение max-limit до тех пор, пока снова не случится понижение скорости менее burst-threshold.
Установим следующие параметры limit-at=128000/128000, max-limit=256000/256000, burst-limit=512000/512000, burst-treshold=192000/192000, burst-time=8 и понаблюдаем, что случится с графиком загрузки канала от одного клиента:
Данный график характерен для случая с закачкой большого файла по протоколу http. После первой секунды средняя загрузка канала будет равна (0+0+0+0+0+0+0+512)/8=64 kbps, что менее установленного нами параметра burst-threshold. После второй секунды средняя скорость будет равна (0+0+0+0+0+0+512+512)/8=128kbps. После третьей секунды средняя скорость превысит показатель burst-threshold. В этот момент скорость резко упадет до значения параметра max-limit и будет держаться на этом уровне до тех пор, пока средняя загрузка канала не станет меньше burst-threshold и снова не произойдет выдача burst скорости.
Алгоритмы Schedulers
Алгоритмы Schedulers предназначены для формирования очередей данных по каким-то параметрам и последующей передаче их шейперу. Например, можно сформировать очереди данных по приоритетам пакетов, адресу источника или получателя. Некоторые алгоритмы обладают функциями ограничения скорости.
PFIFO/BFIFO
Packet/Bytes (FIFO) алгоритм основан на принципе первый пришел-первый ушел. Тот, кто пришел первым, тот и обслуживается первым. Пришедший следующим ждёт, пока обслуживание первого не будет закончено, и так далее.
Для настройки алгоритма используется единственный параметр pfifo-limit (bfifo-limit). Он указывает на количество байт, которые могут храниться в выходном буфере. Не попавшие в буфер пакеты будут разрушаться. Алгоритм применяется для ethernet интерфейсов.
SFQ (Stochastic Fairness Queuing) – этот алгоритм можно назвать «случайно-честным». Он применяется тогда, когда требуется предоставить всем TCP/UDP-подключениям одинаковую возможность по передаче данных.
Для конфигурирования SFQ используется два параметра:
SFQ работает по следующему принципу: алгоритм изымания пакетов из под-очередей одновременно выпускает в выходной интерфейс pcq-allot количество байт, а хэширующий алгоритм добавляет к каждый под-очереди pcq-allot байт, сохраняя при этом равновесие и одинаковую длину всех подочередей. Схему работы SFQ можно сравнить с мясорубкой, в которой через выходную решетку одновременно изо всех дырок в одинаковом количестве выходит фарш.
Алгоритм SFQ рекомендуется использовать в случаях, когда канал сильно загружен и необходимо предоставить приложениям одинаковую возможность по передаче данных. Единственным его недостатком является то, что одно приложение (например торрент клиент), открыв много потоков, может заглушить остальные подключения.
PCQ (Per Connection Queuing) является частным случаем SFQ за тем исключением, что формирование потоков в под-очереди будет происходить в соответствии с неким правилом. Это может быть адрес источника/получателя и порт источника/получателя. Таким образом можно равномерно распределить скорость между участниками вне зависимости от количества открытых подключений. Алгоритм предоставляет следующие параметры для конфигурирования:
Данный алгоритм является основным при необходимости разделить пропускную способность поровну между классами или клиентами. С его помощью можно организовать динамический шейпинг.
Классифицировав под-очереди по адресу источника мы получим отдельную очередь для каждого адреса, соответственно количество потоков с одного адреса не будет играть роли при доступе к выходному интерфейсу. Стоит отметить гибкость такой классификации. Применив ее по источнику к внешнему интерфейсу, в под-очереди будут попадать внешние адреса, так как в этом случае параметр src-address будет все равно содержать адрес, являющийся источником передачи данных. Применив эту же классификацию к внутреннему интерфейсу, в очереди попадут адреса клиентов или классов.
Таким образом, задав два правила, отличающиеся одним параметром, можно разделить поровну как входящий, так и исходящий каналы.
RED (Random Early Detection) — алгоритм, призванный выравнивать пропускную способность и сглаживать скачки, контролируя средний размер очереди. Когда ее размер достигает значения red-min-threshold алгоритм удаляет случайно выбранный пакет. Число удаленных пакетов растет с увеличением среднегого размера очереди. Если размер достигает значения red-max-threshold все пакеты удаляются. Однако случаются ситуации, когда реальный размер очереди (не средний) значительно больше red-max-threshold. В таком случае все пакеты, выходящие за рамки предела red-limit, удаляются.
Использование алгоритма крайне не желательно при присутствии UDP трафика, так как в связи с неразборчивостью алгоритма при удалении пакетов из очереди и принципом работы UDP-протокола, данные могут не дойти до получателя.
На практике алгоритмы SFQ и RED используется крайне редко.
Типы очередей
В Mikrotik предусмотрены два типа очередей, разнесенные на разные закладки в графической утилите Winbox:
Queue Trees
Основные параметры Queue Trees:
Пример
1. Пометим все пакеты, идущие от пользователей на адрес 66.148.73.54 и обратно. Для этого нужно создать 4 правила, два из которых пометят подключения в прямом и обратом направлении, а другие два пометят пакеты в этих подключениях. Необходимо обратить внимание, что очереди работают именно с пакетами, а не помеченными подключениями. Зачастую это создает у новичков вопросы плана: «Я пишу все правильно, а оно не работает. Может это глюки?» Для таких шаманов ниже приведен пример, как нужно делать, чтобы оно работало.
ip firewall mangle add chain=forward src-address=192.168.11.0/24 dst-address=66.148.73.54/32 action=mark-connection new-connection-mark=users-con-up
ip firewall mangle add connection-mark=users-con-up action=mark-packet new-packet-mark=users-up chain=forward
ip firewall mangle add chain=forward src-address=66.148.73.54/32 action=mark-connection new-connection-mark=users-con-down
ip firewall mangle add connection-mark=users-con-down action=mark-packet new-packet-mark=users-down chain=forward
2. Создадим два типа PCQ очереди, подключения в одной из которых мы будем классифицировать по входящему, а другие по исходящему адресу.
3. Создадим очереди для входящего и исходящего трафика
queue tree add name=Download parent=Local max-limit=10240000 burst-limit=200000 burst-time=10
queue tree add parent=Download queue=pcq-download packet-mark=users-down
queue tree add name=Upload parent=Public max-limit=160000 burst-limit=200000 burst-time=10
queue tree add parent=Upload queue=pcq-upload packet-mark=users-up
Как видим, пара правил и такая сложная задача, как динамический шейпинг на определенные адреса с предоставлением пиковой скорости была реализована. На практике обычно приходится применять более сложные правила в сочетании друг с другом, однако для демонстрации возможностей этот очень хорошо подошел.
Практически в Queue Trees мы можем оперировать только ограничением скорости. Остальные параметры, такие как адрес источника, получателя, время суток, протокол, порты и т.д. указываются в разделе Mangle-файервола.
Подобным способом также можно сделать хороший пинг на определенные адреса, даже во время серьезной загрузки канала. Приведем пример таких правил для сервера www.cybernet.by.
Для этого нужно создать четыре правила в Firewall:
# Помечаем все подключения, у которых адрес получателя 195.222.70.250 именем cybernet-connection-up
ip firewall mangle add chain=prerouting dst-address=195.222.70.250 action=mark-connection new-connection-mark=cybernet-connection-up passthrough=yes
# Помечаем пакеты в подключениях cybernet-connection-up именем cybernet-packet-up
ip firewall mangle add chain=forward connection-mark=cybernet-connection-up action=mark-packet new-packet-mark=cybernet-packet-up passthrough=yes
# Помечаем все подключения у которых адрес источника 195.222.70.250 именем cybernet-connection-from
ip firewall mangle add chain=prerouting src-address=195.222.70.250 action=mark-connection new-connection-mark=cybernet-connection-from passthrough=yes
# Помечаем пакеты в подключениях cybernet-connection-from именем cybernet-packet-from
ip firewall mangle add chain=forward connection-mark=cybernet-connection-from action=mark-packet new-packet-mark=cybernet-packet-from passthrough=yes
queue tree add name=»queue1″ parent=global-out packet-mark=cybernet-packet limit-at=0 queue=default priority=1 max-limit=50000 burst-limit=0 burst-threshold=0 burst-time=0s
queue tree add name=»queue2″ parent=global-in packet-mark=cybernet-packet-from limit-at=0 queue=default priority=1 max-limit=50000 burst-limit=0 burst-threshold=0 burst-time=0s
Вышеописанные действия позволят пакетам, приходящим и уходящим с адреса 195.222.70.250, попадать в приоритетные очереди и всегда иметь гарантированные 50 Kbit/s.
Пользуясь вышеописанным примером можно выделить для всех онлайн игр фиксированную гарантированную скорость и создать иерархию классов (правил), распределив, таким образом, пропускную способность между всеми поровну.
Simple Queues
Simple Queues — это простой тип очередей. Для их использования не нужно применять промаркированные пакеты из Firewall, однако при этом теряется некоторая гибкость. В Simple Queues в качестве основных параметров, к которым следует применять правило, относятся адреса источника и получателя. В утилите Winbox на вкладке Advanced можно обнаружить и некоторые другие параметры, однако они не относятся к списку обязательных к заполнению.
Возможности простых очередей Simple Queues:
Стоит отметить, что начиная с версии Mikrotik 2.9 в Simple Queues стало возможным указывать параметр Parent для простых очередей. Таким образом можно строить практически аналогичные деревья классов, как и для Queue Trees за тем исключением, что здесь оперировать будем не пакетами и потоками, а адресами.
Стоит так же помнить, что Simple Queues не что иное, как частный случай Queue Trees. Поэтому создавая новые правила стоит обращать внимание не существует ли уже что-то подобное, оперирующее с теми же адресами, портами или другими параметрами. В случае сходства, приоритет окажется на стороне Queue Trees и ваши простые очереди просто не будут работать.
Перед началом составления правил в Simple Queues необходимо понять что есть входящий и исходящий трафик для нашего провайдера, нашего роутера и наших клиентов. На рисунке изображена стандартная схема направления потоков трафика от провайдера к нашему роутеру и от роутера к клиенту. Стоит обратить внимание, что исходящий трафик клиента для нашего роутера будет являться входящим и наоборот. То же самое можно сказать про нашего провайдера-исходящий трафик для него-это входящий для нас.
Список параметров для конфигурирования простых очередей выглядит следующим образом:
Весьма интересной является возможность управлять входящим и исходящим трафиком вместе. Это позволяет клиентам максимально использовать проплаченный канал.
Пример
Сэмулируем для нашего клиента канал с 64/42 kbit/s с гарантированной скоростью 32/32 kbit/s в будние дни и 256/128 kbit/s с гарантированной скоростью 64/64 kbit/s в выходные.
Результатом нашей работы будет два правила:
queue simple add target-addresses=192.168.11.1/32 limit-at=32000/32000 max-limit=64000/42000 time=00:00:00-00:00:00,mon,tue,wed,thu,fri
queue simple add target-addresses=192.168.11.1/32 limit-at=64000/64000 max-limit=256000/128000 time=00:00:00-00:00:00,sat,sun
В нашем случае первая цифра в паре 32000/32000 означает входящий канал для клиента, а вторая — исходящий. Воспользовавшись нижеприведенной схемой можно инвертировать параметры относительно нашего роутера.
При желании можно позаботиться о быстром открытии страниц, добавив параметры burst-limit и burst-time.
Данное правило можно было бы несколько видоизменить, разделив указанную скорость между всей сетью 192.168.11.0.24. В этом случае для параметра queue нужно указать тип очереди pcq-download, приведенный выше в примере с Queue Trees.
Простые очереди позволяют достаточно просто реализовать возможность предоставления на определенные адреса неограниченной скорости.
Добавим к вышеприведенным правилам ещё одно, которое будет выглядеть следующим образом:
В результате чего клиент с адресом 192.168.11.1 получит доступ к адресу 84.201.225.124 со скоростью от 1 до 2 Мбит/с.
При выделении гарантированной пропускной способности нужно помнить, что сумма limit-at всех клиентов должна быть меньше или равна общей пропускной способности канала. Только в этом случае можно говорить о какой-то гарантированной скорости.
Если у вашего сервера неправильно установлены часы или, к примеру, села батарейка на материнской плате, то можно воспользоваться встроенной в Mikrotik возможностью синхронизации времени с внешним источником.
Ещё одно замечание связанно с тем, что напрямую вписать URI-адрес в поле ввода IP-адреса не представляется возможным, но иногда необходимо, так как многие сайты имеют динамические адреса. Данную проблему можно решить, прописав необходимый адрес ресурса в разделе /ip firewall address-list и дав ему имя, по которому в последствии можно обратиться.
Как видите, MikroTik RouterOS предоставляет огромные возможности по управлению трафиком. Можно создавать различные иерархии правил и управлять потоками данных на достаточно низком уровне. Знание основ шейпинга поможет вам реализовать сложные задачи по управлению трафиком при построении сетей уровня предприятия или провайдера.
Управление трафиком: очереди и шейпинг
Почти все приложения, использующие Интернет, работают через TCP (RFC 793) поверх IP. Протокол IP всего лишь передает пакеты, не заботясь о том, что они могут быть поврежденными, идти в неправильном порядке и т.д. К тому же IP не позволяет адресовать пакет какой-либо конкретной программе. Все эти недостатки устраняются уровнем выше – в TCP. Его характеристики следующие:
Потоковый интерфейс: Все байты информации, отправляемые одним приложением с одной стороны, придут к приложению-получателю с другой стороны в той же последовательности, в какой были посланы. Нет никакого ограничения на размер сообщенния: TCP сам разбивает по своему усмотрению информацию на пакеты.
Достоверность и надежность: Для каждого сегмента (пакета) TCP вычисляет контрольную сумму и отбрасывает его, если она неправильная. Он повторяет пересылку до тех пор, пока не получит подтверждение от получателя о правильном приеме или пока не убедится в том, что канал невозможно использовать и не выйдет время ожидания.
Мультиплексирование: TCP использует механизм портов для осуществления мультиплексирования, тем самым позволяя приложениям-отправителям адресовать данные конкретным приложениям-получателям. Например, веб-серверы, как правило, используют порт 80. Когда браузер соединяется с сервером, он также указывает и порт источника. При этом веб-страница отсылается именно ему. Обычно серверные порты имеют значение меньше 1024 (хотя и не всегда); клиентские порты обычно находятся в диапазоне от 1024 и выше.
Предотвращение перегрузки канала: Наконец, TCP имеет контроль загрузки линии, который позволяет ему определить, не теряются ли ресурсы из-за посылки большего объема трафика, чем может передавать канал.
предотвращение перегрузки канала в TCP
Кроме встроенного простого механизма самосинхронизации, основанного на «окне», ограничивающем количество пересылаемой информации, TCP имеет еще четыре дополнительных механизма, осуществляющих регулировку загрузки канала: медленный старт, предотвращение перегрузки, быстрая перепосылка и быстрое восстановление. Алгоритмы этих механизмов описаны в RFC 2001.
медленный старт
После инициализации соединения, другая сторона сообщает TCP объем данных, приготовленных в буфере. Это значение называется «предложенным размером окна». На установление соединения уходит 3 пакета: инициализирующий пакет с установленным SYN-битом, ответ от хоста-получателя с установленными битами SYN/ACK и финальный пакет от хоста-инициатора с установленным битом ACK.
После вышеописанной процедуры установления соединения локальный (и удаленный) TCP может передавать данные до тех пор, пока окно не заполнится. После этого он должен подождать подтверждений о приеме некоторой части информации. Только после их получения он может продолжить передачу. При получении от удаленного TCP слишком большого значения размера предложенного окна, локальный TCP не начинает сразу же использовать окно полностью. Это необходимо потому что на пути может встретится низкоскоростное соединение, и маршрутизатор, подключенный к нему не сможет буферизировать все накапливающиеся данные пока они не будут переданы через соединение. Таким образом, передающая сторона использует окно предотвращения перегрузки в дополнение к предложенному окну. Окно предотвращения перегрузки сначала имеет размер, равный максимальному размеру сегмента. После получения каждого уведомления о приеме данных, размер этого окна удваивается. Если размер сегмента равен 1460 байтам (что соответствует 1500-байтному пакету Ethernet минус IP- и TCP-заголовки), и приемник предлагает 8192-байтное окно, передатчик установит размер окна предотвращения перегрузки в 1460 байт, передаст первый пакет и будет ждать подтверждения. После получения первого подтверждения, размер окна увеличится до 2920 байт, и предадутся 2 пакета. После получения следующего подтверждения размер окна становится равным 5840 байтам, позволяя пересылать 4 пакета. Один пакет еще не подтвержден, поэтому пересылаются 3 пакета. После получения подтверждения, размер окна увеличится до предложенного.
защита от перегрузки
Защита от перегрузки предлагает другую переменную: границу медленного старта (slow start threshold size (ssthresh)). При инициализации соединения значение ssthresh устанавливается равным 65535 байтам (максимально возможное предложенное окно). Если информация не теряется, алгоритм затяжного пуска будет увеличивать размер окна до тех пор, пока он не станет максимальным. Если же TCP получает пришедшее не по порядку подтверждение, в силу вступает механизм предотвращения перегрузки. В данном случае под пришедшим не по порядку подтверждением подразумевается подтверждение о приеме информации, которая уже была передана, и подтверждение о ее приеме было получено. Это происходит при потере пакета: принимающий TCP отправляет передающему подтверждение на информацию до потерянного пакета, говоря примерно следующее: « Я все еще жду информацию, следующую за тем, что я сейчас подтверждаю» Такая схема необходима из-за того, что подтверждения TCP кумулятивны, т.е. нельзя сказать: «Я получил байты 1000-1499, но потерял 500-999»
После получения повторяющегося подтверждения, передающий TCP принимает неподтвержденную информацию за трагически погибшую из-за перегрузки канала. При этом ssthresh и размер окна предотвращения перегрузки устанавливаются равными половине текущего размера окна до тех пор, пока он равен как минимум двум максимальным размерам сегмента. После этого, окну разрешается увеличиваться очень медленно, чтобы сразу же не вернуться к состоянию перегрузки. Если передающий TCP длительное время не получает никаких подтверждений, он определяет эту ситуацию как массивную перегрузку и инициирует механизм затяжного пуска, понижая при этом значение ssthresh. Таким образом, до тех пор, пока размер окна предотвращения перегрузки меньше или равен значению ssthresh, используется затяжной пуск (окно удваивается после каждого подтверждения), а после него – предотвращение перегрузки (окно медленно увеличивается).
быстрая перепослылка и восстановление
Если TCP получает подряд три идущих не по порядку подтверждения, он решает, что один пакет был потерян (одно или два неправильных подтверждения воспринимаются им как изменение очередности передачи пакетов в сети). После этого он пересылает пакет заново, не дожидаясь тайм-аута. Значение ssthresh устанавливается так же, как и при защите от перегрузки, но размер «перегрузочного» окна принимается равным ssthresh плюс три максимальных сегмента (размер равен количеству информации, успешно полученной приемником, определенному по идущим не по порядку подтверждениям). В результате TCP замедляется, но не сильно, так как при этом через него все еще проходит достаточно большой объем данных.
влияние потери пакетов и задержек на работу TCP
В результате работы вышеописанных механизмов TCP сильно замедляется при потере большого числа пакетов. Ситуация ухудшается, когда время прохождения пакетов туда и обратно (RTT) большое из-за того, что использование окон ограничивает пропускную способность TCP до размера окна, деленного на время прохождения пакетов туда и обратно. Это означает, что даже с максимальным размером окна в 64 кб (без включения высокопроизводительных расширений TCP), производительность TCP на трансконтинентальной линии с задержкой прохождения пакетов туда и обратно в 70 мс не превысит 900 кбит/с. При потере пакета это значение уменьшается вдвое и возвращается к назад только после сотен успешных подтверждений. Таким образом, даже случайная потеря пакета может существенно снизить эффективность использования пропускной способности территориально протяженного соединения TCP-сессией.
Поведение двух основных категорий не-TCP приложений в условиях потери пакетов различно. К первой категории можно отнести мультимедиа (потоковое аудио и видео), ко второй – приложения, основанные на небольших транзакциях, не требующих большого количества служебной информации вроде DNS. Как правило, потоковые аудио и видео не слишком чувствительны к потере пакетов, тем не менее, от нее несколько пострадает качество. Что же касается вещей вроде разрешения имен DNS, то потеря пакетов существенно замедлит индивидуальные транзакции (для них наступает тайм-аут и требуется повторение). Из-за того, что не-TCP приложения не имеют адекватной реакции на потерю пакетов, часто бывает так, что они увеличивают перегрузку канала, продолжая посылать больший объем трафика, чем может передавать соединение.
Несмотря на то, что некоторые потерянные пакеты – результат ошибок в битах на физическом уровне или временных проблем с маршрутизацией, основная причина потерь – перегрузка канала чрезмерным трафиком. Рассмотрим ситуацию, когда, например, скорость подключения маршрутизатора к популярному направлению равна 155 Мбит/с, а для этого направления со скоростью 200 Мбит/с приходит трафик. Первое, что сделает маршрутизатор – поставит пакеты, которые невозможно переслать немедленно, в очередь. IP-трафику свойственны кратковременные вспышки активности длительностью от секунды до нескольких секунд. Очередь сглаживает подобные неоднородности. Ценой этого являются некоторые дополнительные задержки пакетов, но, по крайней мере, пакеты не теряются. Тем не менее, если чрезмерно интенсивный трафик передается длительное время, очередь может переполниться. При этом маршрутизатору ничего не остается, кроме как отбрасывать все входящие пакеты, до тех пор, пока очередь переполнена. Это называется «отбрасывать хвост» («tail drop»). Механизмы защиты от перегрузки разработаны именно для этой ситуации, таким образом, в данном случае все TCP-сессии замедлятся, при этом перегрузка должна исчезнуть. Однако может возникнуть более сложный случай перегрузки, когда трафик представляет собой множество коротких TCP-сессий (например, web или email). В этом случае количества инициализирующих пакетов (в это время TCP еще находится режиме затяжного пуска) может хватить, чтобы вызвать перегрузку. Не-TCP приложения также легко могут вызвать перегрузку, так как они не обладают механизмами защиты от нее.
образование очередей
Образование очередей происходит только в случае, когда интерфейс слишком занят. Если же он свободен, то пакеты передаются без всякой дополнительной обработки. Все стандартные очереди работают по принципу FIFO (first in, first out): пакет, который пришел раньше всех, будет передан первым и т.д. Если очередь заполнена до отказа и приходят новые пакеты, то происходит «отброс хвоста». Более изощренные способы организации очередей часто используют несколько очередей. Пакеты классифицируются в соответствии с потребностями пользователя и затем сортируются по соответствующим очередям. Затем, при освобождении интерфейса, с помощью специального алгоритма выбирается очередь, пакет из которой будет отправлен. Например, маршрутизаторы Cisco поддерживают несколько стратегий организации очередей: FIFO, WQF, RED, по приоритету, произвольные. Следует отметить, что все специальные методики организации очередей дают эффект только в случаях, когда невозможно немедленно отправить пакет через интерфейс. Если же интерфейс свободен и в очереди не находится пакетов, то новый пакет пересылается сразу же.
FIFO
Стратегия FIFO – самая простая. При ее использовании пакеты передаются в том же порядке, в каком приходят. Как правило, ее применяют на быстрых интерфейсах. Чтобы ее включить, необходимо отключить все остальные механизмы организации очередей:
!
interface Serial0
no fair-queue
!
взвешенные очереди (Weighted fair queuing, WQF)
Механизмы, использующие очереди с весами, пытаются разделить пропускную способность между несколькими потоками данных (обычно это TCP-сессии), таким образом, чтобы потоки с большой активностью не захватывали монопольно соединение. Как правило, WQF применяется для низкоскоростных интерфейсов. Включить WQF можно следующим образом:
!
interface Serial0
fair-queue
!
опознание перегрузки (Random early detect, RED)
При переполнении очереди RED начинает отбрасывать пакеты для предотвращения перегрузки канала. Больше всего RED обращает внимания на сессии с наибольшим объемом трафика, поэтому именно они замедляются в первую очередь. При использовании опознания перегрузки с весами (Weighted random early detect), в первую очередь будут отбрасываться пакеты с наименьшим приоритетом. В отличие от WFQ, очередей с приоритетами и произвольных очередей, RED не требовательна к процессорному времени и может применяться на высокоскоростных интерфейсах. Она нуждается в размере очереди на передачу большем, чем стандартные 40 пакетов, чтобы иметь возможность начать отброс пакетов заранее и избежать «отброса хвоста».
!
interface Ethernet0
random-detect
hold-queue 200 out
!
Кстати, в RFC 2309 проблемная группа проектирования Интернет (IETF) рекомендует использовать RED в Интернет-маршрутизаторах.
очереди с приоритетами
При использовании этой методики, трафик классифицируется по приоритетам. Приоритет может быть высоким, нормальным, средним и низким. Если в потоке имеется высокоприоритетный трафик, то он передается в первую очередь, затем передается трафик со средним приоритетом и т.д. Это может замедлить низкоприоритетный трафик или даже совсем остановить его в случае, когда высокоприоритетный трафик забирает всю пропускную способность канала. В нижеописанном примере показано, как включить очереди с приоритетами и установить средний приоритет для DNS и низкий для FTP.
шейпинг и ограничение скорости трафика
При применении шейпинга, происходит подсчет трафика для конкретного интерфейса. Шейпинг может применяться ко всему трафику или же только к тому, который удовлетворяет какому-либо списку. Это происходит не зависимо от того, свободен ли интерфейс, или в очереди находятся пакеты. Когда трафик достигает некоторого заданного пользователем значения, следующие поступающие пакеты становятся в очередь и задерживаются. Таким образом, потребляемая пропускная способность ограничивается на настраиваемое значение.
Ограничение скорости, иногда называемое также ограничением трафика похоже на шейпинг. Отличие заключается в том, что чрезмерный трафик обрабатывается отдельно от обычного, по правилам, настраиваемым пользователем. Наиболее распространенный способ обработки лишнего трафика – отброс его, но существуют и другие способы, например, уменьшение значения поля приоритета в IP-заголовке. В следующем примере включается шейпинг для одного интерфейса и ограничение скорости для другого.
!
interface Serial0
traffic-shape rate 128000 8000 8000 1000
!
interface Serial1
rate-limit output 128000 8000 8000 conform-action transmit exceed-action drop
!
Шейпинг и ограничение скорости обычно применяются, когда необходимо ограничить доступную клиенту пропускную способность, если, например, оплачена низкая, а подключение производится по интерфейсу, имеющему высокую пропускную способность. Однако в данном случае лучше не применять ограничение скорости, так как оно отбрасывает много пакетов, заставляя TCP думать, что линия перегружена. Посему он замедляется, но спустя некоторое время опять пытается ускорить темп, вызывая тем самым очередную потерю пакетов. Шейпинг же всего лишь замедляет пакеты, так что через некоторое время TCP адаптируется к доступной пропускной способности. В следующем примере показана производительность FTP на соединении с применением ограничения скорости до 128к.
ftp>put testfile
local: testfile remote: testfile
150 Opening BINARY mode data connection for ‘testfile’.
100% |**********************************| 373 KB 00:00 ETA
226 Transfer complete.
382332 bytes sent in 35.61 seconds (10.48 KB/s)
Как видно, пропускная способность для FTP составила 84 кбит/с, т.е. примерно две трети от доступной. Как будет вести себя та же передача, на том же соединении, но с применением шейпинга, показано ниже:
ftp>put testfile
local: testfile remote: testfile
150 Opening BINARY mode data connection for ‘testfile’.
100% |**********************************| 373 KB 00:00 ETA
226 Transfer complete.
382332 bytes sent in 24.73 seconds (15.10 KB/s)
На сей раз производительность составила 121 кбит/с, что всего лишь на несколько процентов меньше доступной, учитывая служебную информацию TCP, IP и соединения.
Кроме отбивания атак типа «отказ в обслуживании», ограничение скорости имеет еще одно потенциальное применение, так как в отличие от шейпинга и других механизмов организации очередей может быть применено и к входящему трафику. Когда провайдер договаривается с клиентом о некоторой пропускной способности, он может использовать шейпинг для ограничения доступной клиенту входящей пропускной способности. Но так как невозможно применить шейпинг к входящим в интерфейс пакетам, на клиента возлагается задача шейпинга его исходящего трафика. Для того чтобы убедиться, что клиент не превышает оговоренный лимит трафика, провайдер может дополнительно применить ограничение скорости на входящий трафик.
Iljitsch van Beijnum, перевод Дмитрия Герусса.
Сетевые решения. Статья была опубликована в номере 01 за 2003 год в рубрике технологии