From: Сгибнев Михаил <http://dreamcatcher.ru>
Date: Mon, 8 Jun 2009 17:02:14 +0000 (UTC)
Subject: Оптимизация TCP в Linux, FreeBSD, Solaris, Mac OSX и Windows
Данная инструкция предназначена для описания действий по оптимизации
параметров протокола TCP.
TCP использует параметр, который называют "congestion window", или
CWND, чтобы определить, сколько пакетов можно послать в конечную
единицу времени. Чем больший размер congestion window, тем выше
пропускная способность. Размер congestion window определяется с помощью
алгоритмов TCP "slow start" и "congestion avoidance". Максимальное
значение congestion window зависит от объема буфера, назначенного ядром
для каждого сокета. Для каждого сокета имеется значение размера буфера,
установленное по умолчанию, которое можно изменить программно,
используя системный вызов из библиотек прежде, чем будет открыт данный
сокет. Так же имеется параметр, задающий максимальный размер буфера
ядра. Изменить можно размер как передающего, так и принимающего буфера
сокета.
Чтобы получить максимальную пропускную способность, необходимо
использовать оптимально установленный размер передающего и принимающего
буферов сокета для канала, который вы используете. Если буфера будут
слишком маленькими, то congestion window никогда не будет полностью
открываться. Если передающий буфер слишком большой, то возможны разрывы
управления потоком данных TCP и отправитель может переполнить буфер
получателя, что заставит уменьшить окно TCP. Это, вероятно, случится
быстрее на хосте-отправителе, чем на хосте-получателе. Чрезмерно
большой принимающий буфер - не самая большая проблема, пока у вас есть
лишняя память.
Оптимальный размер буфера можно посчитать как пропускная
способность*задержку используемого канала.
buffer size = 2 * bandwidth * delay
Для определения задержки может быть использована утилита ping или
инструментарий типа [7]pathrate для определения емкости канала от точки
А до точки В (если пропускная способность между точками переменная).
Так как утилита ping дает время прохождения пакета туда и обратно
(RTT), то вместо предыдущей может быть использована следущая формула:
buffer size = bandwidth * RTT
Для примера, если ping показывает 50 ms, и от точки А до точки В
используются каналы 100 BT Ethernet и OC3 (155 Mbps), значение буферов
TCP составит .05 sec * (100 Mbits / 8 bits) = 625 KBytes. (Если вас
гложут сомнения, то 10 MB/s будет хорошим первым приближением для сетей
ESnet/vBNS/Abilene-like).
Есть 2 параметра настройки TCP, о которых Вы должны знать. Это размер
буферов приема/отправки по умолчанию и максимальный размер буферов
приема/отправки. Отметьте, что у большинства современных UNIX OS
максимальный размер буфера по умолчанию только 256 Кбайт! Ниже мы
покажем, как изменить это значение в большинстве современных ОС. Вы
врядли захотите увеличить заданный по умолчанию размер буфера, на
значение больше чем 128 Кбайт, потому что это может неблагоприятно
повлиять на производительность локальной сети. Поэтому вы должны
использовать UNIX вызов setsockopt для буферов приема/отправки, чтобы
установить оптимальный размер буфера для канала, который вы
используете.
Linux
Есть большие отличия между версиями Linux 2.4 и 2.6, но мы сейчас
рассмотрим общие вопросы. Чтобы изменить параметры настройки TCP, вам
необходимо добавить строки, представленные ниже, к файлу
/etc/sysctl.conf и затем выполнить команду sysctl -p.
Как и во всех прочих ОС, размер буферов в Linux очень мал. Применим
следущие настройки:
# increase TCP max buffer size setable using setsockopt()
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# increase Linux autotuning TCP buffer limits
# min, default, and max number of bytes to use
# set max to at least 4MB, or higher if you use very high BDP paths
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
Вы должны также проверить, что следующие параметры установлены в
значение по умолчанию, равное 1.
Отметьте: Вы должны оставить tcp_mem в покое. Значения по умолчанию и
так прекрасны.
Другая вещь, которую вы можете захотеть попробовать, что может помочь
увеличить пропускную способность TCP, должна увеличить размер очереди
интерфейса. Чтобы сделать это, выполните следующее:
ifconfig eth0 txqueuelen 1000
Я получал до 8-кратного увеличения быстродействия, делая такую
настройку на широких каналах. Делать это имеет смысл для каналов
Gigabit Ethernet, но может иметь побочные эффекты, такие как неравное
совместное использование между множественными потоками.
Также, по слухам, может помочь в увеличении пропускной способности
утилита 'tc' (traffic control)
Linux 2.4
В Linux 2.4 реализован механизм автоконфигурирования размера буферов
отправляющей стороны, но это предполагает, что вы установили большие
буфера на получающей стороне, поскольку буфер отправки не будет расти в
зависимости от получающего буфера.
Однако, у Linux 2.4 есть другая странность, о которой нужно знать.
Например: значение ssthresh для данного пути кэшируется в таблице
маршрутизации. Это означает, что, если подключение осуществляет
повторную передачу и уменьшает значение окна, то все подключения с тем
хостом в течение следующих 10 минут будут использовать уменьшенный
размер окна, и даже не будут пытаться его увеличить. Единственный
способ отключить это поведение состоит слкдующем (с правами
пользователя root):
sysctl -w net.ipv4.route.flush=1
Дополнительную информацию можно получить в руководстве [9]Ipsysctl.
Linux 2.6
Начинаясь с Linux 2.6.7 (с обратным портированием на 2.4.27), linux
включает в себя альтернативные алгоритмы управления перегрузкой, помимо
традиционного 'reno' алгоритма. Они разработаны таким образом, чтобы
быстро оправиться от потери пакета на высокоскоростных глобальных
сетях.
Linux 2.6 также включает в себя алгоритмы автоматической оптимизации
буферов принимающей и отправляющей стороны. Может применяться тоже
решение, чтобы устранить странности ssthresh кэширования, что описанно
выше.
Есть пара дополнительных sysctl параметров настройки для 2.6:
# don't cache ssthresh from previous connection
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_moderate_rcvbuf = 1
# recommended to increase this for 1000 BT or higher
net.core.netdev_max_backlog = 2500
# for 10 GigE, use this
# net.core.netdev_max_backlog = 30000
Начиная с версии 2.6.13, Linux поддерживает подключаемые алгоритмы
управления перегрузкой. Используемый алгоритм управления перегрузки
можно задать, используя sysctl переменную
net.ipv4.tcp_congestion_control, которая по умолчанию установлена в
cubic or reno, в зависимости от версии ядра.
Для получения списка поддерживаемых алгоритмов, выполните:
sysctl net.ipv4.tcp_available_congestion_control
Выбор опций контроля за перегрузкой выбирается при сборке ядра. Ниже
представлены некоторые из опций, доступных в 2.6.23 ядрах:
* reno: Традиционно используется на большинстве ОС. (default)
* cubic:CUBIC-TCP (Внимание: Есть бага в ядре Linux 2.6.18
Используйте в 2.6.19 или выше!)
* bic:BIC-TCP
* htcp:Hamilton TCP
* vegas:TCP Vegas
* westwood:оптимизирован для сетей с потерями
Для очень длинных и быстрых каналов я предлагаю пробовать cubic или
htcp, если использование reno желательно. Чтобы установить алгоритм,
сделайте следующее:
sysctl -w net.ipv4.tcp_congestion_control=htcp
Дополнительную информацию по алгоритмам и последствиям их
использования можно посмотреть тут.
Вниманию использующих большие MTU: если вы сконфигурировали свой Linux
на использование 9K MTU, а удаленная сторона использует пекеты в 1500
байт, то вам необходимо в 9/1.5 = 6 раз большее значение буферов, чтобы
заполнить канал. Фактически, некоторые драйверы устройств распределяют
память в зависимости от двойного размера, таким образом Вы можете даже
нуждаться в 18/1.5 = в 12 раз больше!
И наконец предупреждение и для 2.4 и для 2.6: для очень больших BDP
путей, где окно > 20 MB, вы вероятно столкнетесь с проблемой Linux
SACK. Если в "полете" находится слишком много пакетов и наступает
событие SACK, то обработка SACKed пакета может превысить таймаут TCP и
CWND вернется к 1 пакету. Ограничение размера буфера TCP приблизительно
равно 12 Мбайтам, и кажется позволяет избежать этой проблемы, но
ограничивает вашу полную пропускную способность. Другое решение состоит
в том, чтобы отключить SACK.
FreeBSD
Добавьте это в /etc/sysctl.conf и перезагрузитесь:
В FreeBSD 7.0 добавлена функция автокогфигурирования буферов. Но
значения их можно отредактировать, так как по умолчанию буферы 256 KB,
а это очень мало:
У FreeBSD есть кое-какие ограничения, включенным по умолчанию. Это
хорошо для модемных подключений, но может быть вредно для пропускной
способности на высокоскоростных каналах. Если Вы хотите "нормальное"
TCP Reno, сделайте следущее:
net.inet.tcp.inflight.enable=0
По умолчанию, FreeBSD кэширует подробности подключения, такие как
порог slow start и размер окна перегрузки(congestion windows) с
предыдущего подключения на тот же самый хост в течение 1 часа. В то
время как это хорошая идея для веб-сервера, но плохая для тестирования
пропускной способности, поскольку 1 большой случай перегрузки задушит
производительность в течение следующего часа. Чтобы уменьшить этот
эффект, установите это:
net.inet.tcp.hostcache.expire=1
В этом случае мы будем все еще кэшировать значения в течение 5 минут,
по причинам, описанным в этой статье от Centre for Advanced
Internet Architectures (CAIA) at Swinburne University in Autralia. В
ней вы также найдете другую интересную информацию о тюнинге FreeBSD.
Также можно использовать H-TCP patch for FreeBSD
Для получения информации о тюнинге NetBSD, обратитесь к этой статье.
Внимание: у FreeBSD версий ниже 4.10 нет реализации SACK, что сильно
снижает ее производительность по сравнению с другими операционными
системами. Вы необходимо обновиться до 4.10 или выше.
Solaris
Для Solaris просто сделайте загрузочный скрипт (например,
/etc/rc2.d/S99ndd) следующего содержания:
Для получения дополнительной информации, обратитесь к документации Solaris
Windows XP
Самый простой способ настроить TCP под Windows XP состоит в том, чтобы
получить DrTCP из "DSL Reports". Установите "Tcp Receive Window" в
вычесленное значение BDP (e.g. 4000000), включите "Window Scaling"
"Selective Acks" и "Time Stamping".
Провести дополнительную настройку можно с помощью сторонних утилит,
таких как SG TCP Optimizer и Cablenut
Для проверки изменений можно воспользоваться редактором реестра. Наша
цель - вот эти параметры:
# turn on window scale and timestamp option
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParametersTcp1323Opts=3
# set default TCP receive window size
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParametersTcpWindowSize=256000
# set max TCP send/receive window sizes (max you can set using setsockopt call)
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParametersGlobalMaxTcpWindowSize=16777216
Вы можете использовать setsockopt() для программного изменения
значения буферов до размера GlobalMaxTcpWindowSize, или можете
использовать TcpWindowSize для задания значения буферов по умолчанию
всех сокетов. Второй вариант может быть плохой идеей, если у вас мало
памяти.
Для получения дополнительной информации, обратитесь к документам
Windows network tuning, TCP Configuration Parameters,
TCP/IP Implementation Details и Windows 2000/XP Registry Tweaks
Windows Vista
Хорошая новость! У Windows Vista имеется автонастройка TCP.
Максимальный размер окна может быть увеличен до 16 MB. Если вы знаете,
как сделать его больше. дайте мне знать.
Vista также включает в себя "Compound TCP (CTCP)", что очень похоже на
cubic в Linux. Для задействования этого механизма, необходимо
выполнить:
netsh interface tcp set global congestionprovider=ctcp"
Если вы хотите включить/выключить автонастройку, выполните следующие
команды:
netsh interface tcp set global autotunninglevel=disabled
netsh interface tcp set global autotunninglevel=normal
Внимание, команды выполняются с привилегиями Администратора.
Нет возможности увеличить значение буферов по умолчанию, которое
составляет 64 KB. Также, алгоритм автонастройки не используется, если
RTT не больше чем 1 ms, таким образом единственный streamTCP переполнит
этот маленький заданный по умолчанию буфер TCP.
Для получения дополнительной информации, обратитесь к следующим
документам:
* [[http://www.microsoft.com/technet/technetmag/issues/2007/01/CableGuy/default.aspx TCP Receive Window Auto-Tuning in Vista
* [[http://technet.microsoft.com/en-us/windowsvista/aa905086.aspx Enterprise Networking with Windows Vista
* [[http://www.msfn.org/board/index.php?showtopic=87969 Why TcpWindowSize does not work in Vista
Для OSX 10.4, Apple также предоставляет патч Broadband Tuner,
увеличивающий максимальный размер буферов сокета до 8MB и еще кое-что
по мелочи.
Для получения дополнительной информации, обратитесь к OSX Network Tuning Guide.
AIX
Для повышения производительности на SMP системах, выполните:
ifconfig thread
Это позволит обработчику прерываний интерфейов GigE на
многопроцессорной машине AIX выполняться в многопоточном режиме.
IRIX
Добавьте в файл /var/sysgen/master.d/bsd такие строки:
tcp_sendspace
tcp_recvspace
Максимальный размер буфера в Irix 6.5 составляет 1MB и не может быть
увеличен.
1157 Прочтений • [Оптимизация TCP в Linux, FreeBSD, Solaris, Mac OSX и Windows (tcp tune speed optimization linux freebsd sysctl solaris)] [08.05.2012] [Комментариев: 0]