Ограничение скорости передачи трафика. Policer или shaper, что использовать в сети?


    Когда речь заходит об ограничении пропускной способности на сетевом оборудовании, в первую очередь в голову приходят две технологи: policer и shaper. Policer ограничивает скорость за счёт отбрасывания «лишних» пакетов, которые приводят к превышению заданной скорости. Shaper пытается сгладить скорость до нужного значения путём буферизации пакетов. Данную статью я решил написать после прочтения заметки в блоге Ивана Пепельняка (Ivan Pepelnjak). В ней в очередной раз поднимался вопрос: что лучше – policer или shaper. И как часто бывает с такими вопросами, ответ на него: всё зависит от ситуации, так как у каждой из технологий есть свои плюсы и минусы. Я решил разобраться с этим чуточку подробнее, путём проведения нехитрых экспериментов. Полученные результаты подкатом.

    И так, начнём с общей картинки разницы между policer и shaper.


    Как видно, policer срезает все пики, shaper же делает сглаживание нашего трафика. Достаточно неплохое сравнение между policer и shaper можно найти здесь.

    Обе технологии в своей основе используют механизм токенов (token). В этом механизме присутвует виртуальное ограниченное по размеру ведро (token bucket), в которое с некой регулярностью поступают токены. Токен, как проездной, расходуется для передачи пакетов. Если токенов в ведре нет, то пакет отбрасывается (могут выполняться и другие действия). Таким образом, мы получаем постоянную скорость передачи трафика, так как токены поступают в ведро в соответствии с заданной скоростью.

    Может стоило сделать проще?
    Скорость сессии обычно меряется в отведённый промежуток времени, например, за 5 сек или 5 минут. Брать мгновенное значение бессмысленно, так как данные всегда передаются на скорости канала. При этом если мы будем делать усреднение за разные временные интервалы, мы получим разные графики скорости передачи данных, так как трафик в сети не равномерный. Я думаю, любой с этим сталкивался, строя графики в системе мониторинга.

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

    В случае policer’а наполнение ведра происходит каждый раз, когда приходит новый пакет. Количество токенов, которые загружаются в ведро, зависит от заданной скорости policer’а и времени, прошедшего с момента поступления последнего пакета. Если токенов в ведре нет, policer может отбросить пакеты или, например, перемаркировать их (назначить новые значения DSCP или IPP). В случае shaper’а наполнение ведра происходит через равные промежутки времени независимо от прихода пакетов. Если токенов не хватает, пакеты попадают в специальную очередь, где ждут появления токенов. За счёт этого имеем сглаживание. Но если пакетов приходит слишком много, очередь shaper’а в конечном счёте переполняется и пакеты начинают отбрасываться. Стоит отметить, что приведённое описание является упрощённым, так как и policer и shaper имеют вариации (детальный разбор данных технологий займёт объём отдельной статьи).

    Эксперимент


    А как это выглядит на практике? Для этого соберём тестовый стенд и проведём следующий эксперимент. Наш стенд будет включать устройство, которое поддерживает технологии policer и shaper (в моём случае – это Cisco ISR 4000; подойдёт устройство любого вендора аппаратное или программное, которое поддерживает данные технологии), генератор трафика iPerf и анализатор трафика Wireshark.

    Сначала посмотрим на работу policer. Настроим ограничение скорости равным 20 Мбит/с.

    Конфигурация устройства
    policy-map Policer_20
     class class-default
      police 20000000
    interface GigabitEthernet0/0/1
     service-policy output Policer_20
    Используем автоматически выставляемое значение размера ведра токенов (token bucket). Для нашей скорости – это 625 000 байт.

    В iPerf запускаем генерацию трафика в рамках четырёх потоков, используя протокол TCP.

    C:\Users\user>iperf3.exe -c 192.168.115.2 -t 20 -i 20 -P 4
    Connecting to host 192.168.115.2, port 5201
    [  4] local 192.168.20.8 port 55542 connected to 192.168.115.2 port 5201
    [  6] local 192.168.20.8 port 55543 connected to 192.168.115.2 port 5201
    [  8] local 192.168.20.8 port 55544 connected to 192.168.115.2 port 5201
    [ 10] local 192.168.20.8 port 55545 connected to 192.168.115.2 port 5201
    [ ID] Interval           Transfer     Bandwidth
    [  4]   0.00-20.01  sec  10.2 MBytes  4.28 Mbits/sec
    [  6]   0.00-20.01  sec  10.6 MBytes  4.44 Mbits/sec
    [  8]   0.00-20.01  sec  8.98 MBytes  3.77 Mbits/sec
    [ 10]   0.00-20.01  sec  11.1 MBytes  4.64 Mbits/sec
    [SUM]   0.00-20.01  sec  40.9 MBytes  17.1 Mbits/sec
    

    Средняя скорость составила 17.1 Мбит/с. Каждая сессия получила разную пропускную способность. Обусловлено это тем, что настроенный в нашем случае policer не различает потоки и отбрасывает любые пакеты, которые превышают заданное значение скорости.

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


    Чёрная линия показывают суммарный трафик. Разноцветные линии – трафик каждого потока TCP. Прежде чем делать какие-то выводы и углубляться в вопрос, давайте посмотрим, что у нас получится, если policer заменить на shaper.

    Настроим shaper на ограничение скорости 20 Мбит/с.

    Конфигурация устройства
    policy-map Shaper_20
     class class-default
      shape average 20000000
      queue-limit 200 packets
    interface GigabitEthernet0/0/1
     service-policy output Shaper_20

    При настройке используем автоматическое выставляемое значение размера ведра токенов BC и BE равное 8000. Но меняем размер очереди с 83 (по умолчанию в версии IOS XE 15.6(1)S2) на 200. Сделано это сознательно, чтобы получить более чёткую картину, характерную для shaper’а. На этом вопросе мы остановимся более подробно в подкате «Влияет ли глубина очереди на нашу сессию?».
    
    cbs-rtr-4000#sh policy-map interface gigabitEthernet 0/0/1
    
      Service-policy output: Shaper_20
    
        Class-map: class-default (match-all)  
          34525 packets, 50387212 bytes
          5 minute offered rate 1103000 bps, drop rate 0000 bps
          Match: any
          Queueing
          queue limit 200 packets
          (queue depth/total drops/no-buffer drops) 0/0/0
          (pkts output/bytes output) 34525/50387212
          shape (average) cir 20000000, bc 80000, be 80000
          target shape rate 20000000
    


    В iPerf запускаем генерацию трафика в рамках четырёх потоков, используя протокол TCP.

    C:\Users\user>iperf3.exe -c 192.168.115.2 -t 20 -i 20 -P 4
    Connecting to host 192.168.115.2, port 5201
    [  4] local 192.168.20.8 port 62104 connected to 192.168.115.2 port 5201
    [  6] local 192.168.20.8 port 62105 connected to 192.168.115.2 port 5201
    [  8] local 192.168.20.8 port 62106 connected to 192.168.115.2 port 5201
    [ 10] local 192.168.20.8 port 62107 connected to 192.168.115.2 port 5201
    [ ID] Interval           Transfer     Bandwidth
    [  4]   0.00-20.00  sec  11.6 MBytes  4.85 Mbits/sec
    [  6]   0.00-20.00  sec  11.5 MBytes  4.83 Mbits/sec
    [  8]   0.00-20.00  sec  11.5 MBytes  4.83 Mbits/sec
    [ 10]   0.00-20.00  sec  11.5 MBytes  4.83 Mbits/sec
    [SUM]   0.00-20.00  sec  46.1 MBytes  19.3 Mbits/sec
    

    Средняя скорость составила 19.3 Мбит/с. При этом каждый поток TCP получил примерно одинаковую пропускную способность.

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


    Чёрная линия показывают суммарный трафик. Разноцветные линии – трафик каждого потока TCP.

    Сделаем первые промежуточные выводы:

    • В случае policer полезная пропускная способность составила 17.1 Мбит/с. Каждый поток в разные моменты времени имел разную пропускную способность.
    • В случае shaper полезная пропускная способность составила 19.3 Мбит/с. Все потоки имели примерно одинаковую пропускную способность.

    Посмотрим более детально на поведение TCP сессии в случае работы policer и shaper. Благо, в Wireshark достаточно инструментов, чтобы сделать такой анализ.

    Начнём c графиков, на которых отображаются пакеты с привязкой ко времени их передачи. Первый график – policer’а, второй – shaper’а.


    Из графиков видно, что пакеты в случае shaper передаются более равномерно по времени. При этом в случае policer видны скачкообразные разгоны сессии и периоды пауз.

    Анализ TCP сессии при работе policer


    Посмотрим поближе на сессию TCP. Будем рассматривать случай policer’а.

    Протокол TCP в своей работе опирается на достаточно большой набор алгоритмов. Среди них для нас наиболее интересными являются алгоритмы, отвечающие за управление перегрузками (congestion control). Именно они отвечают за скорость передачи данных в рамках сессии. ПК, на котором запускался iPerf, работает под управлением Windows 10. В Windows 10 в качестве такого алгоритма используется Compound TCP (CTCP). CTCP в своей работе позаимствовал достаточно многое из алгоритма TCP Reno. Поэтому при анализе TCP сессии достаточно удобно посматривать на картинку с состояниями сессии при работе алгоритма TCP Reno.

    На следующей картинке представлен начальный сегмент передачи данных.


    1. На первом этапе у нас устанавливается TCP сессия (происходит тройное рукопожатие).

    2. Далее начинается разгон TCP сессии. Работает алгоритм TCP slow-start. По умолчанию значение окна перегрузки (congestion window — cwnd) для TCP-сессии в Windows 10 равно объёму десяти максимальных сегментов данных TCP сессии (MSS). Это означает, что данный ПК может отправить сразу 10 пакетов, не дожидаясь получения подтверждения на них в виде ACK. В качестве начального значения порога прекращения работы алгоритма slow-start (ssthresh) и перехода в режим избегания перегрузки (congestion avoidence) берётся значение максимального окна, которое предоставил получатель (advertised window — awnd). В нашем случае ssthresh=awnd=64K. Awnd – максимальное значение данных, которые получатель готов принять себе в буфер.

      Где посмотреть начальные данные сессии?
      Чтобы посмотреть параметры TCP, можно воспользоваться PowerShell.

      Смотрим, какой глобальный шаблон TCP используется в нашей системе по умолчанию.

      Далее выполняем запрос «Get-NetTCPSetting Internet» и ищем значение величины InitialCongestionWindow(MSS).

      Значение awnd можно найти в пакетах ACK, пришедших от получателя:


      В режиме TCP slow-start размер окна (cwnd) увеличивается каждый раз при получении ACK. При этом оно не может превысить значение awnd. За счёт такого поведения, мы имеем практически экспоненциальный рост количества передаваемых пакетов. Наша TCP сессия разгоняется достаточно агрессивно.

      Передача пакетов в режиме TCP slow-start
      1. ПК устанавливает TCP-соединение (№1-3).
      2. Отправляет 10 пакетов (№4-13), не дожидаясь подтверждения (ACK), так как cwnd=10*MSS.
      3. Получает ACK (№14), который подтверждает сразу два пакета (№4-5).
      4. Увеличивает размер окна Cwnd=(10+2)*MSS=12*MSS.
      5. Отправляет дополнительно три пакета (№15-17). По идее ПК должен был отправить четыре пакета: два, так как он получил подтверждение на два пакета, которые были переданы ранее; плюс два пакета из-за увеличения окна. Но в реальности на самом первом этапе система шлёт (2N-1) пакетов. Найти ответ на этот вопрос мне не удалось. Если кто-то подскажет, буду благодарен.
      6. Получает два ACK (№18-19). Первое ACK подтверждает получение удалённой стороной четырёх пакетов (№6-9). Второе — трёх (№10-12).
      7. Увеличивает размер окна Cwnd=(12+7)*MSS=19*MSS.
      8. Отправляет 14 пакетов (№20-33): семь новых пакетов, так как получили ACK на семь ранее переданных пакетов, и ещё семь новых пакетов, так как увеличилось окно.
      9. И так далее.



    3. Policer никак не препятствует разгону сессии. Токенов в ведре много (при инициализации policer’а ведро заполнено токенами полностью). Для скорости 20 Мбит/с размер ведра по умолчанию выставляется равным 625000 байт. Таким образом, сессия разгоняется в момент времени практически до 18 Мбит/с (а мы помним, что у нас таких сессий четыре). Размер окна cwnd достигает максимального значения и становится равным awnd, а значит, cwnd = ssthersh.

      cwnd = ssthersh
      Когда cwnd = ssthersh точного ответа, произойдёт ли смена алгоритма с slow-start на алгоритм congestion avoidance, я найти не смог. RFC точного ответа не даёт. С практической точки зрения это не очень важно, так как размер окна дальше расти не может.

    4. Так как наша сессия разогналась достаточно сильно, токены очень быстро тратятся и в конечном итоге заканчиваются. Ведро не успевает наполнятся (наполнение токенами идёт для скорости 20 Мбит/с, при этом суммарная утилизация всеми четырьмя сессиями в моменте времени приближается к 80 Мбит/с). Policer начинает отбрасывать пакеты. А значит, до удалённой стороны они не доходят. Получатель шлёт Duplicate ACK (Dup ACK), которые сигнализируют отправителю, что произошла потеря пакетов и нужно передать их заново.


      После получения трёх Dup ACK наша TCP сессия переходит в фазу восстановления после потери (loss recovery, включающую алгоритмы Fast Retransmit/Fast Recovery). Отправитель устанавливает новое значение ssthresh = cwnd/2 (32K) и делает окно cwnd = ssthresh+3*MSS.


    5. Отправитель пытается сразу же начать заново передать потерянные пакеты (работает алгоритм TCP Fast Retransmission). При этом продолжают приходить Dup ACK, назначение которых — искусственно увеличить окно cwnd. Это нужно, чтобы как можно быстрее восстановить скорость сессии из-за потери пакетов. За счёт Dup ACK окно cwnd вырастает до максимального значения (awnd).

      Как только было отправлено количество пакетов, укладывающихся в окно cwnd, система останавливается. Для продолжения передачи данных ей нужны новые ACK (не Dup ACK). Но ACK не приходят. Все повторные пакеты отбрасываются policer’ом, так в ведре закончились токены, а времени, чтобы их восполнить, прошло слишком мало.

    6. В таком состоянии система ждёт, пока не сработает таймаут на получение нового ACK от удалённой стороны (Retransmission timeout — RTO). С этим как раз и связаны наши большие паузы, которые видны на графиках.

    7. После срабатывания таймера RTO система переходит в режим slow-start и устанавливает ssthresh = FlightSize/2 (где FlightSize – количество не подтверждённых данных), а окно cwnd = 1*MSS. Далее снова делается попытка передать потерянные пакеты. Правда, теперь отправляется всего один пакет, так как cwnd = 1*MSS.


    8. Так как в течение некоторого времени система ничего не передавала, в нашем ведре успели накопиться токены. Поэтому в конечном итоге пакет доходит до получателя. А значит, мы получим новое ACK. С этого момента система начинает передать потерянные ранее пакеты в режиме slow-start. Происходит разгон сессии. Как только размер окна cwnd превышает значение ssthresh, сессия переходит в режим congestion avoidance.

      В алгоритме Compound TCP для регулирования скорости передачи используется окно отправителя (sending window — wnd), которое зависит от двух взвешенных величин: окна перегрузки (cwnd) и окна задержки (delay window — dwnd). Cwnd, как и раньше, зависит от полученных ACK, dwnd зависит от величины задержки RTT (round trip time). Окно wnd растёт только один раз за период времени RTT. Как мы помним, в случае slow-start окно cwnd росло при получении каждого ACK. Поэтому в режиме congestion avoidance сессия разгоняется не так быстро.

    9. Как только сессия разгоняется достаточно сильно (когда пакетов передаётся больше, чем есть токенов в ведре), опять срабатывает policer. Начинают отбрасываться пакеты. Далее следует фаза loss recovery. Т.е. весь процесс повторяется заново. И так продолжается, пока у нас не завершится передача всех данных.


      TCP сессия при работе policer выглядит как лестница (идёт фаза передачи, за которой следует пауза).

    Анализ TCP сессии при работе shaper


    Теперь давайте посмотрим поближе на сегмент передачи данных для случая shaper. Для наглядности возьмём аналогичный масштаб, как и для графика policer на Рис.6.


    Из графика мы видим всё ту же лесенку. Но размер ступенек стал существенно меньше. Однако если приглядеться к графику на Рис. 10, мы не увидим небольших «волн» на конце каждой ступеньки, как это было на Рис. 9. Такие «волны» были следствием потери пакетов и попыток их передачи заново.

    Рассмотрим начальный сегмент передачи данных для случая shaper.


    Происходит установление сессии. Далее начинается разгон в режиме TCP slow-start. Но этот разгон более пологий и имеет ярко выраженные паузы, которые увеличиваются в размере. Более пологий разгон обусловлен тем, что размер ведра по умолчанию для shaper всего (BC+BE) = 20 000 байт. В то время как для policer размер ведра — 625 000 байт. Поэтому shaper срабатывает существенно раньше. Пакеты начинают попадать в очередь. Растёт задержка от отправителя к получателю, и ACK приходят позже, чем это было в случае policer. Окно растёт существенно медленнее. Получается, что чем больше система передаёт пакетов, тем больше их накапливается в очереди, а значит, тем больше задержка в получении ACK. Имеем процесс саморегуляции.

    Через некоторое время окно cwnd достигает значения awnd. Но к этому моменту у нас накапливается достаточно ощутимая задержка из-за наличия очереди. В конечном итоге при достижении определённого значения RTT наступает равновесное состояние, когда скорость сессии больше не меняется и достигает максимального значения для данного RTT. В моём примере среднее RTT равно 107 мс, awnd=64512 байт, следовательно, максимальная скорость сессии будет соответствовать awnd/RTT= 4.82 Мбит/с. Примерно такое значение нам и выдал iPerf при измерениях.

    Но откуда берутся ярко выраженные паузы в передаче? Давайте посмотрим на график передачи пакетов через устройство с shaper в случае, если у нас всего одна TCP сессия (Рис.12). Напомню, что в нашем эксперименте передача данных происходит в рамках четырёх TCP сессий.


    На этом графике очень хорошо видно, что нет никаких пауз. Из этого можно сделать вывод, что паузы на Рис.10 и 11 обусловлены тем, что у нас одновременно передаётся четыре потока, а очередь в shaper одна (тип очереди FIFO).


    На Рис.13 представлено расположение пакетов разных сессий в очереди FIFO. Так как пакеты передаются пачками, они будут располагаться в очереди таким же образом. В связи с этим задержка между поступлением пакетов на приёмной стороне будет двух типов: T1 и T2 (где T2 существенно превосходит T1). Общее значение RTT для всех пакетов будет одинаковым, но пакеты будут приходить пачками, разнесёнными по времени на значение T2. Вот и получаются паузы, так как в момент времени T2 никакие ACK к отправителю не приходят, при этом окно сессии остаётся неизменным (имеет максимальное значение равное awnd).

    Очередь WFQ
    Логично предположить, что, если заменить одну общую очередь FIFO на несколько для каждой сессии, никаких ярко выраженных пауз не будет. Для такой задачи нам подойдёт, например, очередь типа Weighted Fair Queuing (WFQ). В ней для каждой сессии создаётся своя очередь пакетов.

    policy-map Shaper
     class shaper_class
      shape average 20000000   
      queue-limit 200 packets
      fair-queue




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

    А вот и наш график распределения пакетов по времени передачи ровно в том же масштабе, что и на Рис. 11. Никаких пауз нет.



    Стоит отметить, что очередь типа WFQ позволит нам получить не только более равномерное распределение пропускной способности, но и предотвратить «забивание» одного типа трафика другим. Мы всё время говорили про TCP, но в сети также присутствует и UDP трафик. UDP не имеет механизмов подстройки скорости передачи (flow control, congestion control). Из-за этого UDP трафик может с лёгкостью забить нашу общую очередь FIFO в shaper’е, что драматически повлияет на передачу TCP. Напомню, что, когда очередь FIFO полностью заполнена пакетами, по умолчанию начинает работать механизм tail-drop, при котором отбрасываются все вновь пришедшие пакеты. Если у нас настроена очередь WFQ, каждая сессия пережидает момент буферизации в своей очереди, а значит, сессии TCP будут отделены от сессий UDP.

    Самый главный вывод, который можно сделать после анализов графиков передачи пакетов при работе shaper’а – у нас нет потерянных пакетов. Из-за увеличения RTT скорость сессии адаптируется к скорости shaper’а.

    Влияет ли глубина очереди на нашу сессию?
    Конечно! Изначально (если кто-то об этом ещё помнит) мы изменили глубину очереди с 83 (значение по умолчанию) на 200 пакетов. Сделали мы это для того, чтобы очереди хватило для получения достаточного значения RTT, при котором суммарная скорость сессий становиться примерно равна 20 Мбит/с. А значит, пакеты «не вываливаются» из очереди shaper'а.

    При глубине в 83 пакета очередь переполняется быстрее, нежели достигается нужное значение RTT. Пакеты отбрасываются. Особенно ярко это проявляется на начальном этапе, когда у нас работает механизм TCP slow-start (сессия разгоняется максимально агрессивно). Стоит отметить, что количество отброшенных пакетов несравнимо меньше, чем в случае с policer, так как увеличение RTT приводит к тому, что скорость сессии растёт более плавно. Как мы помним, в алгоритме CTCP размер окна в том числе зависит от значения RTT.



    Графики утилизации пропускной способности и задержки при работе policer и shaper

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

    График утилизации пропускной способности:




    В случае policer мы видим скачкообразный график: сессия разгоняется, потом наступают потери, и её скорость падает. После чего всё повторяется снова. В случае shaper наша сессия получает примерно одинаковую пропускную способность на протяжении всей передачи. Скорость сессии регулируется за счёт увеличения значения RTT. На обоих графиках вначале можно наблюдать взрывной рост. Он обусловлен тем, что наши вёдра изначально полностью заполнены токенами и TCP-сессия, ничем не сдерживаемая, разгоняется до относительно больших значений (в случае shaper это значение в 2 раза меньше).

    График задержки RTT для policer и shaper (по-хорошему, это первое о чём мы вспоминаем, когда говорим про shaper):


    В случае policer (первый график) задержка RTT для большинства пакетов минимальна, порядка 5 мс. На графике также присутствуют существенные скачки (до 340 мс). Это как раз моменты, когда пакеты отбрасывались и передавались заново. Тут стоит отметить, как Wireshark считает RTT для TCP трафика. RTT – это время между отправкой оригинального пакета и получением на него ACK. В связи с этим, если оригинальный пакет был потерян и система передавала пакет повторно, значение RTT растёт, так как точкой отсчёта является в любом случае момент отправки оригинального пакета.

    В случае shaper задержка RTT для большинства пакетов составила 107 мс, так как они все задерживаются в очереди. Есть пики до 190 мс.

    Выводы


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

    1. Shaper предоставляет нам на 13% больше полезной пропускной способности, чем policer (19.3 против 17.1 Мбит/с) при заданном ограничении в 20 Мбит/с.

    2. В случае shaper'а пропускная способность распределяется более равномерно между сессиями. Наилучший показатель может быть получен при включении очереди WFQ. При работе policer’а присутствуют существенные пики и падения скорости для каждой сессии.

    3. При работе shaper'а потерь пакетов практически нет (конечно, это зависит от ситуации и глубины очереди). При работе policer’а мы имеем существенные потери пакетов – 12.7%.

      Если policer настроен ближе к получателю, наша сеть фактически занимается прокачкой бесполезного трафика, который будет в итоге отброшен policer’ом. Например, в разрезе глобальной сети интернет это может является проблемой, так как трафик режется зачастую ближе к получателю.

    4. В случае shaper'а у нас появляется задержка (в нашем эксперименте – это дополнительные 102 мс). Если трафик примерно одинаков, без существенных всплесков, очередь shaper’а находится в относительно стабильном состоянии и больших вариаций в задержке (jitter) не будет. Если трафик будет иметь взрывной характер, мы можем получить повышенное значение jitter.

      Вообще наличие очереди может достаточно негативно сказываться на работе приложений – так называемый эффект излишней сетевой буферизации (Bufferbloat). Поэтому с глубиной очереди надо быть аккуратными.

    5. Благодаря разным типам очередей shaper позволяет нам учитывать приоритезацию трафика при ограничении скорости. И если встаёт необходимость отбрасывать пакеты, в первую очередь делать это для менее приоритетных. В policer'е добиться этого сложнее, а для некоторых схем невозможно.

    6. Policer и shaper подвержены ситуации, когда UDP трафик может «забить» TCP. При настройке этих технологий необходимо учитывать данный факт.

    7. Работа shaper'а создаёт бОльшую нагрузку на сетевое устройство, чем работа policer'а. Как минимум требуется память под очередь.

    Можно отметить ещё один факт, хоть и не относящийся непосредственно к задаче ограничения скорости. Shaper позволяет нам настраивать различные типы очередей (FIFO, WFQ и пр.), обеспечивая тем самым разнообразные уровни приоритезации трафика при его отправке через устройство. Это очень удобно в случаях, если фактическая скорость передачи трафика отличается от канальной (например, так часто бывает с выходом в интернет или WAN каналами).

    Исследование влияния policer в сети интернет
    В этом году при поддержке Google было проведено исследование, в котором анализировался негативный эффект работы policer’а в сети интернет. Было определено, что от 2% до 7% потерь видео трафика по всему Миру вызвано срабатыванием policer’а. Потери пакетов при непосредственной работе policer’а составили порядка 21%, что в 6 раз больше, чем для трафика, который не подвержен срабатыванию данной технологии. Качество видео трафика, который подвергся обработке policer’ом, хуже, чем в случае, если policer не срабатывал.

    Для борьбы с негативным эффектом работы policer’а предлагаются следующие меры в зависимости от точки их применения.

    Для интернет-провайдеров:

    1. В policer’е уменьшить размер ведра (burst size). Это приведёт к тому, что TCP сессия не сможет слишком сильно разогнаться, пока есть свободные токены, и быстрее начнёт адаптацию под реальную пропускную способность.
    2. Вместо policer’а использовать shaper (с небольшой глубиной очереди).
    3. Использовать и shaper, и policer одновременно. В этом случае shaper располагается чуть раньше, чем policer. Shaper задерживает пакеты, сглаживая колебания. Из-за такой задержки policer успевает аккумулировать достаточное количество токенов, чтобы передавать трафик. Потери в таком случае минимизируются.

    Однозначных рекомендаций по поводу конфигурации shaper в документе не даётся. Shaper может обеспечивать положительный эффект как при большом, так и при маленьком значении размера ведра (даже если BC = 8 000 байт). Также нет однозначной рекомендации по поводу глубины очереди. Маленькая глубина приводит к лишним потерям, большая может негативно сказаться на задержках в сети. Во всех случаях есть свои плюсы и минусы.

    Для контент-провайдеров предлагается ограничивать скорость отправки трафика на сервере, чтобы избегать включения policer’а. Но на практике оценить реальную скорость канала не всегда просто. Второй метод — избегать взрывной передачи трафика за счёт модификации алгоритмов TCP: использовать TCP Pacing (отправлять пакеты с привязкой к RTT, а не к моменту получения ACK) и изменить схему работы фазы loss recovery (на каждый полученный ACK слать только один новый пакет).

    Таким образом, нет однозначного ответа на вопрос, что лучше использовать: shaper или policer. Каждая технология имеет свои плюсы и минусы. Для кого-то дополнительная задержка и нагрузка на оборудование не так критична, как для другого. А значит выбор делается в сторону shaper. Кому-то важно минимизировать сетевую буферизацию для борьбы с джиттером – значит наша технология policer. В ряде случаев вообще можно использовать одновременно обе эти технологии. Поэтому выбор технологии зависит от каждой конкретной ситуации в сети.
    CBS
    Компания

    Комментарии 15

      +2
      Очень мощная статья.
      Всегда было интересно, что происходит с пакетами, когда достигается лимит, а тут такой разбор TCP :)
        +1
        -Я думал, что знаю TCP… (с)
        0
        К сожалению, с Cisco работал мало, вопрос по Linux: правильно ли я понимаю, в tc на Linux реализован только policer, а собственно шейпинг трафика включается собственно механизмом TCP («медленный старт» и другие алгоритмы), который и сглаживает трафик после потери пакетов?
          0
          По поводу «tc на Linux», к сожалению, не подскажу. Но TCP slow-start и пр. алгоритмы функций шейпинга и полисера не реализуют. Их задачи совсем другие: обеспечение максимально допустимой скорости передачи данных в рамках TCP сессии. Шейпер и полисер стоят по другу сторону баррикад, ограничивая эту скорость.
            0
            В tc реализованы как policer, так и shaper трафика. Причём алгоритмов шейпинга несколько, с различными возможностями и сложностью настройки. Это именно шейперы, которые в случае необходимости, «придерживают» пакеты в буфере, выравнивая скорость передачи данных. Алгоритмы контроля перегрузки (congestion control) протокола TCP на конечных хостах уже после подстраиваются под задержки и потери сегментов, замедляя и ускоряя передачу данных.
            +2
            Хорошая статья, спасибо. Теперь есть на что сослаться, а не объяснять все самому.
            Небольшое замечание.
            В данном контексте правильно говорить не «полоса пропускания» (единицы измерения Гц), а «пропускная способность» (единицы измерения б/с).
              +1
              Вы правы, спасибо!
              +1
              Сергей, добрый день. Не могу понять одной вещи.
              Вот есть у нас параметр cwnd, о нём пишется:
              По умолчанию значение окна перегрузки (congestion window — cwnd) для TCP-сессии в Windows 10 равно 10. Это означает, что данный ПК может отправить сразу 10 пакетов, не дожидаясь получения подтверждения на них в виде ACK.

              То есть параметр cwnd вроде как отвечает за количество отправляемых пакетов (полагаю, правильно тут — сегментов, но не суть)

              Далее есть параметры ssthresh и awnd:
              В качестве начального значения порога прекращения работы алгоритма slow-start (ssthresh) и перехода в режим избегания перегрузки (congestion avoidence) берётся значение максимального окна, которое предоставил получатель (advertised window — awnd). В нашем случае ssthresh=awnd=64K

              То есть, «в нашем случае awnd=64 000», и речь уже об объёме данных.
              Итого cwnd показывает количество сегментов, awnd — объём данных.
              Я не могу понять, как в таком случае сопоставляются данные параметры во фразе
              Размер окна cwnd достигает максимального значения и становится равным awnd, а значит, cwnd = ssthersh.

              Неужели в нашем случае количество отправляемых пакетов может достигнуть числа 64000?
                0
                Не пытаясь ответить на вопрос, действительно ли cwnd == awnd с алгоритмической точки зрения, замечу, что 64000*1460 (стандартный MSS) = 93440 килобайт. Это не очень много. Здесь ведь не идет речь о том, чтобы отправлять эти данные без ACK. Это максимальное количество данных, которое может быть «в проводе». Т. е. ACK'и могут и в нормальной ситуации должны отправляться чаще, а число в 93440 является критической точкой, после которой передача трафика останавливается до получения ACK.
                  0
                  Я просто увидел фразу
                  Это означает, что данный ПК может отправить сразу 10 пакетов, не дожидаясь получения подтверждения на них в виде ACK.

                  и подумал, что cwnd — это всегда количество пакетов, которые можно отправить без ACK. Возможно что подумал неверно, отсюда и вопрос.
                  Я в данной теории слаб, поэтому и хочу потдверждения\опровежения, что в рамках tcp сессии существует возможность отправить 64 000 сегмента не получая ACK от получателя
                  0
                  Все значения (cwnd, awnd, ssthresh) определяют именно объём данных. И когда я писал, что в начале сессии можно передать 10 пакетов без подтверждения, я в неком роде упрощал. И видимо зря. Это внесло путаницу. Изначальное значение cwnd=10*MSS. Т.е. ваше замечание по поводу сегментов тоже верное. Всё-таки мы на транспортном уровне.
                    0
                    Спасибо за ответ в частности, и за статью в принципе!
                    То есть в итоге, есть некоторый коэффициент, ну допустим «K» (который в начале равен именно 10 в нашем случае), и растёт именно этот «K», пока произведение K*MSS (читай cwnd) не достигнет awnd? Именно этот «K» и определяет «количество отправляемых сегментов без ACK». И например при MSS = 1460 байт, «K» достигнет максимума при значении 64000/1460≈43
                      0
                      Если говорить чуточку абстрактно, всё верно. Просто в самом RFC коэффициента «К» нет. Есть только:
                      CONGESTION WINDOW (cwnd): A TCP state variable that limits the amount
                      of data a TCP can send. At any given time, a TCP MUST NOT send
                      data with a sequence number higher than the sum of the highest
                      acknowledged sequence number and the minimum of cwnd and rwnd.
                  0
                  хороший пример шейпера для ISR Вы привели, а есть у кого-нибудь для Cisco ASA? и желательно для туннеля IPSec (cryptomap based VPN)?
                  что-то типа такого:
                  access-list LIMIT-10Mbps extended permit tcp any 10.30.0.0 255.255.0.0
                  
                  class-map LIMIT-10Mbps
                  match access-list LIMIT-10Mbps
                  
                  policy-map LIMIT-10Mbps
                    class LIMIT-10Mbps
                      police output  10000000
                       queue-limit 100 packets
                  
                  Interface GigabitEthernet1/1
                   service-policy LIMIT-10Mbps service-policy LIMIT-10Mbps interface office-users
                  

                  будет работать?! где 10.30.0.0 255.255.0.0 — сети доступные через VPN Site-to-Site
                    0
                    Шейпинг поддерживался только на одноядерных ASA (5505, 5510 и пр.). Причём работает крайне нестабильно. На новых такого функционала вообще нет. Пример конфигурации.

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое