Всем привет!
Бывало ли у вас такое, что ставите файл на закачку, и скорость медленно, но верно возрастает, затем, в какой-то момент, резко снижается, затем опять возрастает? Закачка файла в один поток не обеспечивает полную скорость канала? Запускаете торрент-клиент, и пинг в игре сильно прыгает? Используете 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:
Как видите, CUBIC в отстающих. Он значительно повысил RTT на полной утилизации 3G канала, в то время как Westwood+ и NewReno более-менее справляются с этой проблемой.
Давайте взглянем на количество ретрансмиссий:
Как видно из графика, у CUBIC относительно большое количество ретрансмиссий
В то же время, он лидирует в скорости передачи данных за единицу времени.
Что это значит? Это значит, что с использованием Westwood+ или NewReno вы сможете комфортней серфить интернет, пока у вас скачивается большой файл.
Тест высокоскоростного канала
Этот тест взят из технического отчета алгоритма YeAH-TCP за 2006 год. Теоретически, YeAH является самым продвинутым алгоритмом и нацелен работать как можно лучше на высокоскоростных линиях, на линиях с высокой задержкой или высокими потерями пакетов.
Тесты делались с импользованием канала пропускной способностью в 500 mbit/s
В эффективной передаче данных в зависимости от RTT лидирует YeAH
Зависимость эффективной передачи данных и потери пакетов, опять YeAH занимает первое место
К сожалению, с 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 или Veno. Для проводных каналов хорошим выбором может быть YeAH (если у вас не наблюдается с ним проблем), H-TCP или Illinois.
Несколько советов. Если у вас уже ядро 3.6+, обязательно включите net.ipv4.tcp_fastopen. Никаких проблем с несовместимыми серверами это не добавит, а handshake для поддерживаемых ускорит.
Также рекомендую установить net.ipv4.tcp_slow_start_after_idle в 0, это добавит скорости для SPDY и других keep-alive соединений.
Автор: ValdikSS