Оптимизация работы сетевого стека ОС Linux для высоконогруженных WEB серверов

На производительность nginx очень большое влияние имеет настройка ОС.

В данной статье затронуты некоторые очень важные аспекты настройки ОС Linux, в частности Ubuntu 12.04 для достижения максимальной производительности сетевой подсистемы.

Внесите следующие изменения в /etc/sysctl.conf, чтобы применить изменения выполните команду sysctl -p.

Увеличим длину очереди для входящих пакетов. Значение 30000 это нормальное значение даже для 10GigE, если у Вас входящий канал не превышает 1Gbit/s, то выставлять значение переменной netdev_max_backlog более 10000 не имеет смысла.

net.core.netdev_max_backlog=10000

Сделать это можно внеся изменения в /etc/sysctl.conf, как уже говорилось:

echo 'net.core.netdev_max_backlog = 10000' >> /etc/sysctl.conf

или на ходу:

sysctl –w net.core.netdev_max_backlog=10000

или так

echo 10000 > /proc/sys/net/core/netdev_max_backlog

Посмотреть текущее значение:

cat /proc/sys/net/core/netdev_max_backlog

Далее увеличиваем количество возможных подключений к сокету аналогичным образом. По умолчанию значение равно 128, что при высоко нагруженном сервере будет являться узким местом.

net.core.somaxconn=262144

Включаем tcp_syncookies, эта опция необходима для того, чтобы вы могли использовать параметрnet.ipv4.tcp_max_syn_backlog описанный ниже.

net.ipv4.tcp_syncookies=1

Увеличиваем буфер под хранение SYN запросов на соединение. Значение по умолчанию 1024, что очень мало для нагруженных серверов.

net.ipv4.tcp_max_syn_backlog = 262144

Увеличим возможное количество сокетов в состоянии TIME_WAIT

net.ipv4.tcp_max_tw_buckets = 720000

Разрешаем быструю утилизацию сокетов находящихся в состоянии TIME_WAIT

net.ipv4.tcp_tw_recycle = 1

Включаем tcp_timestamps иначе не будет работать опция tcp_tw_reuse описанная ниже

net.ipv4.tcp_timestamps = 1

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

net.ipv4.tcp_tw_reuse = 1

Уменьшаем время пребывания сокета в состоянии FIN-WAIT-2

net.ipv4.tcp_fin_timeout = 30

Уменьшаем временной интервал попытки определения жизнеспособности соединения. По умолчанию 7200, т.е. через 2 часа после того как через соединение прошел последний пакет, система пошлет keep-alive запрос, чтобы узнать состояние соединения. Уменьшим этот параметр до 30 минут (1800 сек).

net.ipv4.tcp_keepalive_time = 1800

Уменьшим количество посылок keepalive запросов и интервалов между запросами. По умолчанию делается 9 попыток с интервалом в 75 секунд, что в свою очередь займет 9*75=675 сек (11,25 минут), что в сочетании с параметром по умолчанию net.ipv4.tcp_keepalive_time = 7200 (7200 сек = 2 часа) дает нам значение 2 часа 11,25 минут — минимальное значение времени после которого соединение будет закрыто нашей стороной после прохождения через это соединение последнего пакета. Это очень большой интервал.
Устанавливаем 7 попыток с интервалом в 30 секунд:

net.ipv4.tcp_keepalive_probes = 7
net.ipv4.tcp_keepalive_intvl = 30

Увеличиваем размеры буферов выделяемых под сетевые соединения.

net.core.wmem_max = 33554432
net.core.rmem_max = 33554432
net.core.rmem_default = 8388608
net.core.wmem_default = 4194394
net.ipv4.tcp_rmem = 4096 8388608 16777216
net.ipv4.tcp_wmem = 4096 4194394 16777216

Тут перечислены все параметры для удобства копирования в /etc/sysctl.conf:

# Оптимизация работы сетевого стека ОС
net.core.netdev_max_backlog=10000
net.core.somaxconn=262144
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_max_tw_buckets = 720000
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1800
net.ipv4.tcp_keepalive_probes = 7
net.ipv4.tcp_keepalive_intvl = 30
net.core.wmem_max = 33554432
net.core.rmem_max = 33554432
net.core.rmem_default = 8388608
net.core.wmem_default = 4194394
net.ipv4.tcp_rmem = 4096 8388608 16777216
net.ipv4.tcp_wmem = 4096 4194394 16777216

Также Вам следует увеличить длину очереди для исходящих пакетов на каждом из сетевых интерфейсов. Делается это с помощью штатной команды ifconfig:

ifconfig eth0 txqueuelen 10000

или

ip link set eth0 txqueuelen 10000

Для сохранения значения очереди после перезагрузки внесети изменения в /etc/rc.local до строчки exit 0:

/sbin/ifconfig eth0 txqueuelen 10000
/sbin/ifconfig eth1 txqueuelen 10000

или, как менее предпочтительный вариант, внести изменения в файл /etc/network/interfaces:

up ifconfig $IFACE txqueuelen 10000

Получить данные о работе сетевых интерфесов можно с помошью команд:

ethtool -S eth0
ifconfig (см. данные в полях txqueuelen:, RX packets, TX packets)
netstat -s
netstat -i
cat /proc/net/dev
cat /proc/net/netstat

Более подробно о сетевых параметрах, которые вы можете менять через sysctl можно прочесть Ipsysctl tutorial 1.0.4. Перевод находится здесь. А также описание некоторых sysctl переменных ядра Linux и здесь.

One thought on “Оптимизация работы сетевого стека ОС Linux для высоконогруженных WEB серверов

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.