MyTetra Share
Делитесь знаниями!
О, смотри-ка какое хорошее место. Дайте два!
Оптимизируем сетевую подсистему
25.04.2013
21:57
Раздел: root - Linux

 

Оптимизируем сетевую подсистему

 

 

Не так давно пришлось мне поднимать сервер на основе любимого Debian Lenny, и в ходе этого всплыли некоторые нюансы по настройке сети под высокие нагрузки. По горячим следам - сегодняшняя заметка.

Итак, имеем систему с Debian Lenny 5.0.4, с тремя сетевыми картами на борту: встроенной Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 02), и двумя Intel Corporation 82541PI Gigabit Ethernet Controller (rev 05). Сервер является шлюзом для сети с нагрузкой примерно 50Мбит/с для множества клиентов, внутренняя сеть - eth1, внешняя - eth2. eth0 - упомянутая встроенная сетевая, почти не используется.

Начнём с настроек параметров сетевых карт. Для гигабитных сетевых рекомендуется установить размер очереди отправки txqueuelen как минимум в 1000. По умолчанию для Realtek система поступает именно так, а вот для основных Intel почему-то ставит этот параметр в 100. Может, ей и лучше знать, но сетевой народ рекомендует именно 1000 и больше, прислушаемся к рекомендациям

 

/sbin/ifconfig eth1 txqueuelen 1000/sbin/ifconfig eth2 txqueuelen 1000

 /etc/rc.local для автоматической загрузки при включении системы.

Размер очереди получения регулируется через net.core.netdev_max_backlog. В /etc/sysctl.conf добавляем

 

net.core.netdev_max_backlog = 8192

Поддержку flow-control для сетевых рекомендуют выключить (тут ничего умного - почему и для чего - не скажу), поддержку NAPI (polling в терминологии FreeBSD), включить. И то, и другое стоит по умолчанию, так что эти моменты я пропускаю.

Теперь разберёмся с механизмом CPU affinity. Данный механизм позволяет равномерно распределять irq между процессорами в SMP-системах, что весьма и весьма полезно. По умолчанию Debian справляется с этим достаточно успешно, но в случае двух сетевых на шлюзе есть смысл жёстко приписать обработку прерываний от конкретной сетевой конкретному процессору. Делается это следующим образом:

 

echo [cpu_bitmask] >  /proc/irq/[eth_irq]/smp_affinity

 

  • cpu_bitmask - битовая маска cpu ( 1 - первый cpu, 10 - второй, 100 - третий, 101 - третий и первый, и т.д.; переводим двоичную маску в десятичное шестнадцетиричное значение и используем в команде);

     

  • eth_irq - номер прерывания для нужной сетевой карты, узнать который можно из /proc/interrupts

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

 

echo 1 >  /proc/irq/20/smp_affinityecho 2 >  /proc/irq/18/smp_affinity

 /etc/rc.local)

Для проверки, сработали ли указанные манипуляции, периодически выводим /proc/interrupts:

 

ns:~# watch -n 3 cat /proc/interrupts           CPU0       CPU1         0:         33          1   IO-APIC-edge      timer  1:          1          1   IO-APIC-edge      i8042  7:          0          0   IO-APIC-edge      parport0  8:          1          0   IO-APIC-edge      rtc0  9:          0          0   IO-APIC-fasteoi   acpi14:    7120791    7802969   IO-APIC-edge      ata_piix15:          0          0   IO-APIC-edge      ata_piix16:         55         55   IO-APIC-fasteoi   uhci_hcd:usb4, HDA Intel17:          8          8   IO-APIC-fasteoi   HDA Intel18:         28 1315936560   IO-APIC-fasteoi   uhci_hcd:usb3, eth219:          0          0   IO-APIC-fasteoi   uhci_hcd:usb220: 1390434990       2329   IO-APIC-fasteoi   eth123:          0          0   IO-APIC-fasteoi   uhci_hcd:usb1, ehci_hcd:usb51276:    5529851    6200894   PCI-MSI-edge      eth0NMI:          0          0   Non-maskable interruptsLOC:  489299683 1752920893   Local timer interruptsRES:    4642455    6796305   Rescheduling interruptsCAL:      22526      19892   function call interruptsTLB:     513168     561022   TLB shootdownsTRM:          0          0   Thermal event interruptsTHR:          0          0   Threshold APIC interruptsSPU:          0          0   Spurious interruptsERR:          0

 

Теперь о параметрах ядра, задаваемых через /etc/sysctl.conf. В моём случае часть параметров задаётся также при выполнении скрипта arno-iptables-firewall, если Вы его тоже используете - имейте ввиду, что скрипт этот выполняется позже подгрузки значений из sysctl.conf и, следовательно, его параметры имеют более высокий приоритет.

ns:~# cat /etc/sysctl.conf...# Мои параметры ядра# См. также параметры arno-iptables-firewall

 

# Если Ваш сегмент сети содержит множество хостов и Вы получаете в логах сообщение# "Neighbour table overflow.", необходимо увеличить следующие параметрыnet.ipv4.neigh.default.gc_thresh1 = 2048net.ipv4.neigh.default.gc_thresh2 = 4096net.ipv4.neigh.default.gc_thresh3 = 8192

 

net.ipv4.tcp_mtu_probing = 1

 

# Максимельное число одновременных подключений к сокетуnet.core.somaxconn = 4096

 

# Таймауты для протокола TCP. Первый в arno-iptables-firewall устанавливается в 1800, подправьте скрипт.net.ipv4.tcp_keepalive_time = 180net.ipv4.tcp_keepalive_probes = 5net.ipv4.tcp_keepalive_intvl = 30

 

# Таймаут для сброса соединения в таблице ip_conntrack, в секундах. По умолчанию равен 5 дням, это как-то слишком.net.netfilter.nf_conntrack_tcp_timeout_established = 28800

 

# Устанавливаем в 256 Кб размер буферов по умолчанию для приема и отправки данных через сокетыnet.core.rmem_default = 262144net.core.wmem_default = 262144

 

# Устанавливаем в 8Мб максимальный размер буфера сокетовnet.core.rmem_max = 8388608net.core.wmem_max = 8388608

 

# Максимальный размер очереди пакетовnet.core.netdev_max_backlog = 8192

 

# Тюнинг буферов для TCP и UDP соединенийnet.ipv4.tcp_rmem = 8192 87380 8388608net.ipv4.tcp_wmem = 8192 65536 8388608

 

net.ipv4.udp_rmem_min = 16384net.ipv4.udp_wmem_min = 16384

 

net.ipv4.tcp_mem = 8388608 12582912 16777216net.ipv4.udp_mem = 8388608 12582912 16777216

 

# Приоритет начала своппинга. Значение от 0 до 100: 0 -  не свопим вообще, 100 - свопим всё что возможно.vm.swappiness = 70

Очень важный параметр - net.ipv4.netfilter.ip_conntrack_max, он указывает максимальное число записей в таблице соединений. У меня установлен в 262144 (через arno-iptables-firewall). Если параметр слишком мал, вы будете получать в логах сообщение "kernel: ip_conntrack: table full, dropping packet.". Слишком большим его ставить тоже нет смысла, это будет только отъедать оперативную память. Лучше всего выставить параметр побольше, пару-тройку дней помониторить значение /proc/sys/net/netfilter/nf_conntrack_count, найти максимальное, увеличить его вдвое на перспективу, и уже полученный результат установить для net.ipv4.netfilter.ip_conntrack_max.Также можно увеличить размерность хэша через параметр hashsize модуля ip_conntrack, но я этого не делал, так что на Ваше усмотрение; почитать об этом можно здесь.

Пока это всё. Добавления/исправления/пожелания и ссылки на полезную информацию по теме горячо приветствуются.

Так же в этом разделе:
← Содержание ...
 
MyTetra Share v.0.35
Яндекс индекс цитирования