Пользователь
47,1
рейтинг
6 февраля 2013 в 21:27

Администрирование → TCP Congestion Control или Почему скорость прыгает

Всем привет!

Бывало ли у вас такое, что ставите файл на закачку, и скорость медленно, но верно возрастает, затем, в какой-то момент, резко снижается, затем опять возрастает? Закачка файла в один поток не обеспечивает полную скорость канала? Запускаете торрент-клиент, и пинг в игре сильно прыгает? Используете 3G-модем (или другую линию с относительно большой потерей пакетов) и не можете это терпеть?
Наверняка вы винили во всем ваш роутер, либо обвиняли своего провайдера в кривой настройке шейпера? Это влияет, но виноваты не они.
Итак, встречайте:

TCP Congestion Control, или TCP Congestion Avoidance Algorithm.


Что это такое?


Вкратце ­— алгоритмы, которые пытается сделать все возможное, чтобы обеспечить наиболее быструю скорость передачи данных между двумя узлами, передающими данные через TCP. Они управляют размером TCP-окна и могут ориентироваться на RTT (Round Trip Time — время от отправки запроса до получения ответа), потерю пакетов, время ожидания отправки пакета из очереди и т.д. Каждый алгоритм по разному ведет себя в той или иной ситуации и нет какого-то универсального.

Долгое время, в ходу были алгоритмы Reno, разработанный в 1990 году, и BIC. Первый применялся во всех ОС Windows до XP, а второй — в Linux до 2.6.18. Затем, в Windows Vista появился новый алгоритм Compound TCP, а в Linux сменили BIC на Cubic.

Какие есть алгоритмы?


Их достаточно много. В ядре Linux 3.7 имеются:
  • BIC TCP
  • CUBIC TCP
  • Highspeed TCP
  • H-TCP
  • TCP Hybla
  • TCP-Illinois
  • TCP Low Priority
  • TCP Vegas
  • TCP NewReno
  • TCP Veno
  • TCP Westwood+
  • YeAH-TCP

BIC, CUBIC, Highspeed, H-TCP, NewReno, Illinois — эти алгоритмы созданы для так называемых long fat networks ­— длинных (а значит, с высоким RTT) и быстрых сетей. TCP Hybla здорово ведет себя на спутниковых линках, а Veno создан для беспроводных сетей с высокой потерей пакетов. TCP Low Priority вообще сложно назвать congestion алгоритмом, т.к. он мало что делает, а просто пытается отправить пакет без очереди, TCP Vegas иногда применяют на серверах с большим количеством подключений, т.к. он обеспечивает почти постоянную скорость, хоть и далеко не идеальную. Westwood+ — комбинированный алгоритм, YeAH-TCP самый младший из них, но самый интересный, т.к. ведет себя более-менее во всех случаях.
Более подробно о самих алгоритмах можно прочитать в посте casperrr

Тест 3G


К сожалению, CUBIC, который используется по умолчанию во всех дистрибутивах, совершенно не подходит, например, для 3G-соединений. Ниже представлен график сравнения 4 алгоритмов congestion avoidance для HSDPA сетей за конец 2012 года из TCP Congestion Control over HSDPA: an Experimental Evaluation:
image

Как видите, CUBIC в отстающих. Он значительно повысил RTT на полной утилизации 3G канала, в то время как Westwood+ и NewReno более-менее справляются с этой проблемой.
Давайте взглянем на количество ретрансмиссий:

image

Как видно из графика, у CUBIC относительно большое количество ретрансмиссий

image

В то же время, он лидирует в скорости передачи данных за единицу времени.

Что это значит? Это значит, что с использованием Westwood+ или NewReno вы сможете комфортней серфить интернет, пока у вас скачивается большой файл.

Тест WiMAX и WiFi каналов


Тест взят из Comparative Performance Evaluation of TCP Variants in WiMAX (and WLANs) Network Configurations — еще одного интересного сравнения алгоритмов для беспроводных сетей.

В тесте №1 используется соединение компьютер-wimax.роутер-wimax.клиент с пропускной способностью между компьютером и роутером в 100 мбит/с и RTT в 45 мс и соотношением DL:UL 1:1 между wimax роутером и клиентом.
Зависимость эффективной передачи данных от потери пакетов:
image

Чуть изменим тест. В тесте №2 используется схема компьютер-роутер1-роутер2-wimax.роутер-wimax.клиент, где RTT 10 мс. между компьютером и первым роутером, далее используется 10 мбит/с канал с 25 мс. RTT, между вторым и wimax роутером канал опять 100 мбит/с c RTT в 10 мс.

image
image

Как видно из графиков, лидерство держит Westwood.
Картина для WiFi схожа с WiMAX:

image

Тест высокоскоростного канала


Этот тест взят из технического отчета алгоритма YeAH-TCP за 2006 год. Теоретически, YeAH является самым продвинутым алгоритмом и нацелен работать как можно лучше на высокоскоростных линиях, на линиях с высокой задержкой или высокими потерями пакетов.
Тесты делались с импользованием канала пропускной способностью в 500 mbit/s

В эффективной передаче данных в зависимости от RTT лидирует YeAH
image

Зависимость эффективной передачи данных и потери пакетов, опять YeAH занимает первое место
image

К сожалению, с YeAH на ядре 3.7 какие-то проблемы, через некоторое время он весит систему software interrupt'ами. Такого поведения не наблюдается на 3.6.

Как поменять?


Сменить Congestion Algorithm достаточно просто, всего одна строка:
sysctl -w net.ipv4.tcp_congestion_control=westwood
Где вместо westwood можно вставить названия из /lib/modules/.../kernel/net/ipv4/tcp_....ko без префикса tcp_.

Вместо заключения


На каналах вроде домашнего вайфая, рекомендую использовать Westwood или H-TCP. Для проводных каналов хорошим выбором может быть YeAH (если у вас не наблюдается с ним проблем), H-TCP или Illinois.

Несколько советов. Если у вас уже ядро 3.6+, обязательно включите net.ipv4.tcp_fastopen. Никаких проблем с несовместимыми серверами это не добавит, а handshake для поддерживаемых ускорит.
Также рекомендую установить net.ipv4.tcp_slow_start_after_idle в 0, это добавит скорости для SPDY и других keep-alive соединений.
@ValdikSS
карма
632,0
рейтинг 47,1
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Администрирование

Комментарии (40)

  • 0
    Насчет последних параметров можнл поподробнее? Каков прирост в тестах?
    Еще у меня есть одна проблема с Wifi. Я уже замучался. Имеем игру например L4D2 или Dota 2. Как только я присоединяюсь к сети с планшета у меня тут же повышаеься пинг на ноуте вплоть до потеря соединения. Ноут находится далеко, через 3 стены. Но iperf удавалось держать на 20 мбитах.
    Также у меня в доме очень много Wifi точек. И как я понимаю, когда кто то на соседнем или на этом же канале начинает что то скачинать, у меня происходит такие же глюки сети.
    Как вариант думал переходить на 5 ггц точку. Но мне пока что надо стабилизировать то что есть. Например уменьшить задержку уменьшив скорость или рутер перенастроить как нибудь. Нужно решение и под винду и под линукс.
    • +1
      Думаю, в вашем случае виноват вайфай. Дело в том, что чем дальше расположено одно из устройств, подключенных к сети, тем хуже работает вся сеть. В вашем случае, попробуйте сменить канал на 14, если ваши устройства поддерживают его, либо на 13, форсируйте 802.11n и выставите 802.11n Preamble в Green Field.
    • 0
      сеть 802.11n, а планшет — a/b/g?
      гляньте сюда (http://habrahabr.ru/post/149447/) и оцените, что из этого применимо к вашей ситуации
    • 0
      Переход на 5GHz может помочь, но тут есть другая проблема — он хуже проходит через стены, и у вас может просто не пробить 3 стены до ноута.
  • 0
    Я как-то тестировал разные алгоритмы в условиях LFN (10Gb/s, 0.9ms ping, ёмкость сети 550кб), по ощущениям лучше всего себя показали Vegas и Illinosis, но разница там была на грани ощутимого. Меня интересовала в первую очередь latency от TCP, а не «выжимаемая скорость», причём в условиях недоутилизации канала.

    В итоге по результатам сравнения я решил не заморачиваться и остаться на чём есть, ибо погрешность измерений была выше, чем разница между лучшими и средними.
    • 0
      Судя по условиям теста, пытались выжать максимум для задачи типа iSCSI over 10GBase?
      А что такое ёмкость сети?
      • 0
        А что такое ёмкость сети?

        en.wikipedia.org/wiki/Bandwidth-delay_product
        • 0
          Спасибо. Первый раз, откровенно говоря, встретил такой русскоязычный термин.
      • 0
        Не максимум пропускной способности, но максимум iops'ов, да. Кстати, от тюнинга tcp в этих условиях зависит значительно, но больше от начальных размеров окон, а не от алгоритма.
  • +1
    Есть еще proprietary алгоритмы, такие как
    en.wikipedia.org/wiki/FAST_TCP
    en.wikipedia.org/wiki/Zeta-TCP

    Тестировали оба. На long fat networks они значительно (+50%) обходят все остальные алгоритмы.
    Разработчики говорят что они так-же хороши и для wifi / 3G.
    • 0
      Вы, случаем, не тестировали TCP-Fit vs YeAH vs FAST-TCP? Fit и Fast должны быть где-то рядом, а вот на каком уровне находится YeAH по сравнению с ними я, честно говоря, не нашел. Но FIT выглядит пушкой просто, судя по вот этому документу, он просто какое-то нереальное ускорение дает.
      image
      • +1
        Настолько детально не сравнивали, и более того, про TCP-Fit я даже не слышал :)
        Очень интересно проверить его в действии.

        Еще очень интересное замечание касательно Zeta TCP. При его использовании значительно падает скорость на коротких линках с небольшой latency. Причем падает значительно, процентов на 25
    • 0
      Скажите, пожалуйста, Вы случайно не знаете, можно ли эти алгоритмы пощупать в живую и какой порядок цен на реализации?
      • +1
        Zeta вы можете протестировать совершенно без проблем, у них есть Free Trial:
        download.appexnetworks.com

        С Fast TCP немного сложнее. В конце прошлого года их купили Akamai. Осталось некоторое кол-во компаний, которые работают по старым договорам, но в целом тенденция к тому, что Fast TCP будет похоронен самим Акамаем.

        По ценам все довольно гибко, можно торговаться. Из того что я знаю цены варьируются от одной, до нескольких сотен $ за лицензию.
        • 0
          Спасибо за ссылку!
          Я изначально где-то час исследовал их сайт на предмет сравнений, описаний и т.д., но только после Вашей ссылки заметил надпись «Free Trial» прямо в меню основного сайта.
  • 0
    А есть возможность как-то это оптимизировать на Windows? Я понимаю, что на Linux'e уйма вариантов, но всё же.
    • +3
      К сожалению, никак, наверное. В Windows есть выбор только между Compound и Reno.
    • 0
      Есть и не мало, примерно понять что можно подкрутить можно тут.
    • 0
      P.S.
      Скрипт для более оптимальной настройки чем по умолчанию для 7, 2008, 2008R2 и более новых ОС (с некоторыми оговорками ибо часть параметров уже установлено в оптимальное положение. Для полной настройки на 8, 2012 и старше требуется powershell, там ещё есть профили настраиваемые и можно задать разные настройки для адаптеров локалки и инета, например, удобно в общем :) )
      @echo off
      
      echo Optimizing TCP/IP parameters...
      
      if "%1" == "/RSS_supported_by_HW_and_configured" (
      
      	echo RSS supported by hardware and configured properly confirmed.
      	echo Enabling RSS...
      
      	netsh interface tcp set global rss=enabled
      
      ) else (
      
      	echo Setting RSS is default mode...
      
      	netsh interface tcp set global rss=default
      
      )
      
      echo Set compound TCP as CTCP...
      
      echo Applicable only to Windows 7, Server 2008, Server 2008 R2.
      echo On older versions, you get an error - ignore it,
      echo there is a mechanism is not supported, and it does not change.
      echo In newer versions, you also get an error, but they install
      echo this parameter is not required and therefore will be ignored,
      echo so that further action from you just does not required.
      
      netsh interface tcp set global congestionprovider=ctcp
      
      echo Enabling TCP Chimney Offload
      
      netsh int tcp set global chimney=enabled
      
      echo Set as default NetDMA...
      
      netsh interface tcp set global netdma=default
      
      echo Set as default DCA for NetDMA...
      
      netsh interface tcp set global dca=default
      
      echo Enabling ECN...
      
      netsh interface tcp set global ecn=enabled
      
      echo Enabling TCP Timestamps (RFC 1323)...
      
      netsh interface tcp set global timestamps=enabled
      
      echo Enabling TCP WSH...
      
      netsh interface tcp set heuristics wsh=enabled
      
      echo Optimizing TCP/IP parameters done.
      



      пример его вызова с подтверждением работоспособности и поддержки RSS
      @echo off
      
      call install /RSS_supported_by_HW_and_configured
      

  • +1
    Вопрос: в связке Линукс-десктоп <= Ethernet => Роутер <= 3G => Интернет даст ли какой-нибудь эффект настройка TCP Congestion Control для обеспечения более «плавной» связи в Skype (иногда звук и картинка лагают) и где это нужно настраивать, на десктопе или на роутере?
    • +1
      Настраивать это нужно на десктопе. Для скайпа, скорее всего, никаких изменений не будет, т.к. скайп использует UDP.
  • –1
    Как бы на mac их поменять.
    • +1
      sysctl -w net.inet.tcp.newreno=1
      Вроде можно выбрать только NewReno и не NewReno (не знаю, какой в этом случае используется).
      • 0
        class is not implemented.
  • 0
    Имеет смысл менять алгоритм на Linux-серверах подключенных на 100Мбит/1Гбит? Если да, то на какой, YeAH?
    • 0
      Думаю да. В некоторых статьях рекомендуют htcp, но я не смог найти с ним адекватных сравнений, все уровня «Это обычный TCP, а это HTCP!»
      • 0
        Спасибо, надо будет почитать-потестировать.
        • 0
          А вообще, YeAH и TCP-Fit выглядят самыми современными, но с YeAH у меня не удалось как-то (надо бы баг на багзилле завести), а Fit не имплементирован в линукс.
    • +1
      Думаю да. На канале 1GE разные алгоритмы по скорости передачи данных уже могут отличаться раза в 2-3.
      Я сейчас использую алгоритм illinois, правда задачи у меня не совсем стандартные серверные.
      У меня при последнем тестировании illinois и yeah давали результаты практически совпадающие в пределах погрешности, чуть хуже был westwood, остальные значительно хуже. Канал 1GE, используемый в тестах rtt min/avg/max/mdev = 5.511/5.520/5.553/0.048 ms.
  • +2
    Какие-то вещи в заголовке вообще к тсп и его поведению прямого отношения не имеют. Так если при загрузке канала пинг сильно увеличивается вместо появления потерь — значит провайдер шейпит. Но чаще полисит ака рэйт-лимит. Это проще и ближе к тому, какое ограничение накладывали бы физические параметры канала. При полисинге или ограничении физикой при загрузке канала под завязку кучей потоков потери для пинга будут неизбежны, тут как бы тсп ни при чем. Потери могут превращаться в увеличение задержки именно за счет провайдера.

    На всяких там вайфай и 3ж все так плохо, потому что потери случайны, тсп трудно отличить случайные потери от потерь от перегрузки, отсюда такие фатальные проблемы. Для всевозможных беспроводных вещей придумали habrahabr.ru/post/155977/
  • 0
    ccfit.nsu.ru/~tregub/WirelessLectureNotes.pdf

    с. 48
    Влияние ошибок передачи на производительность TCP

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

    Итак, если за секунду теряется лишь 20 бит (каждый стотысячный, например), то механизмы TCP в результсдерживают нормальную доставку миллиона бит (каждого второго бита)!
  • 0
    Если есть следующая проблема — удалённый HTTP сервер имеет жётскую настройку таймаута (ну скажем 5 секунд).

    При обращении к серверу в несколько потоков по ADSL, этот таймаут часто срабатывает.
    Получается как будто есть два соединения к серверу, но Linux почему-то слишком долго посылает данные по одному из них,
    при этом второе соединение простаивает эти 5 секунд и случается таймаут.

    tcp_congestion_control=cubic

    Я так понимаю это тоже может быть связанно с tcp_congestion_control? Вроде westwood помогает, хотя не понятно…
  • 0
    У известного немецкого дата-центра H на нелимитированном канале 100Mbit и при пинге 60ms наблюдается такой эффект из Москвы: небольшие файлы, например картинки, скачиваются очень медленно, например картинки 10Kb-100Kb по firebug могут загружаться одинаково долго за 250ms-500ms, то есть на скорости менее 100kb/sec. При этом если загружать большой многомегабайтный файл (хоть http, хоть ftp), то видно как в начале идут те же самые 100kbps, а затем разгоняется полностью до ширины моей канала 30Mbps.
    Бывает и так — страница 10kb генерируется за 10ms, по firebug отдаётся 350ms, а затем уже загрузка маленьких картинок идёт как раз уже на скорости пинга 60ms. Но стоит через пару секунд после загрузки страницы кликнуть на большую 100кб картинку — 500ms-1000ms.

    CentOs 5.9 2.6.18,KeepAlive on, MaxKeepAliveRequests 100, KeepAliveTimeout 15, net.ipv4.tcp_congestion_control = bic, net.ipv4.tcp_slow_start_after_idle = 1

    Вопрос — как это побороть, в какую сторону смотреть и как убрать это первоначальное затормаживание? Это именно эффект от net.ipv4.tcp_slow_start_after_idle или маленький KeepAlive? Пробую сразу после загрузки жать Ctrl+F5 до истечения таймаута KeepAlive — цифры все такие же. Или это дата-центр специально так шейпит?
    • 0
      Вот что пишут news.ycombinator.com/item?id=1796698
      ipv4.tcp_slow_start_after_idle, which is on by default on most distros, applies to keepalive connections. This causes your keepalive connection to return to slow start after TCP_TIMEOUT_INIT which is 3 seconds. Not probably want you want or expect. For example, if you have keepalives of say 10s, you'd expect that a request after say 5s would have it's congestion window fully open from previous requests, but the default behaviour is to go back to slow start, and close your congestion window back down. So you want to tune this to off on your image servers and other keepalive systems.

      The tuning which I talk about is to actually increase the default initial congestion window size. The result being an advantage for non-keepalive connections and keepalives. There is no sysctl parameter that will allow for this control. This behaviour is hardcoded into the tcp stack, and hence requires direct modification and a recompiled kernel.
      То есть без рекомпиляции ядра вроде никак.
    • 0
      Сначала обновите ядро. Начиная с 3.1 или 3.2 произошло много изменений в TCP. Также посмотрите начальный размер TCP окна через sysctl.
      Ну и у вас все еще BIC в качестве congestion algo, он вообще агрессивный.
  • 0
    через некоторое время он весит систему software interrupt'ами
    — «вешает», может быть? 3 раза перечитал.
  • 0
    Спасибо за статью. Однако у меня вопрос: до этого (до вашей статьи) для меня TCP Congestion Control Algorithm-ы это были Fast Retransmit and Recovery (FRR) и Selective ACK (SACK), а в ваших примерах TCP Veno и проч. Правильно ли я понял, что BIC, CUBIC, Highspeed, H-TCP, NewReno, Illinois — это как пакеты, которые описывают работу TCP Congestion алгоритмов. Т.е. возможно в одном из этих «пакетов» также присутствует алгоритмы Fast Retransmit и Selective ACK?
    • +1
      Правильно ли я понял, что BIC, CUBIC, Highspeed, H-TCP, NewReno, Illinois — это как пакеты, которые описывают работу TCP Congestion алгоритмов.
      Да, так и есть. На последних ядрах выбор таков:

      tcp_cdg.ko.xz tcp_dctcp.ko.xz tcp_diag.ko.xz tcp_bic.ko.xz tcp_hybla.ko.xz tcp_vegas.ko.xz tcp_yeah.ko.xz tcp_htcp.ko.xz tcp_illinois.ko.xz tcp_westwood.ko.xz tcp_veno.ko.xz tcp_highspeed.ko.xz tcp_scalable.ko.xz tcp_lp.ko.xz
      И есть еще reno (newreno, на самом деле), который прямо в ядре
      Т.е. возможно в одном из этих «пакетов» также присутствует алгоритмы Fast Retransmit и Selective ACK?
      Fast Retransmit реализован в Reno, вы можете его активировать следующим образом:

      echo reno | sudo tee /proc/sys/net/ipv4/tcp_congestion_control

      Но действительно ли вы этого хотите? Reno — классический алгоритм, современны алгоритмы, вроде YeAH, лучше.
  • 0
    ---
  • 0
    Мне, кстати, вот, интересно почему столько лет прошло, а Illinois до сих пор нельзя выбрать дефолтным в конфиге ядра при компиляции :)

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