|
|||||||
Оптимизируем сетевую подсистему
Время создания: 25.04.2013 21:57
Раздел: root - Linux
Запись: Yurons/mytetra/master/base/13669162794qnk25lqdy/text.html на raw.github.com
|
|||||||
|
|||||||
Не так давно пришлось мне поднимать сервер на основе любимого 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
В моём случае команды для привязки двух сетевых карт
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, но я этого не делал, так что на Ваше усмотрение; почитать об этом можно здесь. Пока это всё. Добавления/исправления/пожелания и ссылки на полезную информацию по теме горячо приветствуются. |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|