Pull to refresh

Comments 42

Замечательная заметка. Вообще такому тюнингу, в случае многоядерного сервера, место не только на роутерах. У нас 8-ядерный сервер вставал раком при копировании большого объёма данных по сети. Оказалось райд и сетевуха «сидели» на одном проце. Разнесли — всё устаканилось.
про FreeBSD хорошо написано тут, в целом же, linux лучше справляется со значительной сетевой нагрузкой
Это все здорово, а для роутера (Linksys WRT54GL) на DD-WRT можно такое сделать? Или ему уже не судьба больше 50 мбит в WAN прокачать?
если туда впаять xeon то справится.
видел в песочнице, пожалел, что кончились инвайты. Кстати, а почему нет пометки, что из песочницы? В последнее время она автоматически добавлялась под заголовком топика.
Потому что я получил инвайт за другой пост, а этот пост написал уже как зарегистрированный пользователь :)
Полезная статья, спасибо!
По-моему заголовок широк по смыслу, может быть, стоит переименовать в «Управление прерываниями в Linux»?
за статью спасибо, однако не понятно, почему на 150 мегабитах в секунду встает эта проблема.

на моей практике:
раздача крупной статики на 400-600 мегабит/секунду ограничивалась дисковой подсистемой.
router\firewall на достаточно слабой (~гигагерц) однопроцессовой машине не загружен при 100 мегабитном потоке в одну сторону и 70 мегабитном в другую. 2 карточки (на самом деле их 3, не меняет сути дела).

Могу логи выдать в момент нагрузки, если интересно.

Вопрос, видимо к постановке проблемы, входящим условиям. Не к описанному методу решения.
В моем случае сервер занимается маршрутизацией и в обработке трафика принимают активное участие шейпер, ULOG, файрволл. Основную нагрузку дают шейпер и ULOG, маршрутизация и фильтрация — на их фоне практически не нагружают систему.
Было бы отлично еще сюда написать и про настройки шейпинга (в отдельном посте)
Это есть в планах, в том числе использование хэш-таблиц для меньшей нагрузки шейпира на систему.
шейпЕра, конечно же, извините. Просто изначально писал «шейпинга».
замечательно, будем ждать.
действительно, было бы неплохо.
Ну а если не хотите ждать, мне кажется здесь lartc.org/ есть всё
Спасибо, обязательно почитаю.
Выкиньте ULOG. ipt_netflow наше все!
Спасибо, обязательно попробую. Вообще ссылка на проект ipt_netflow уже с месяц висит в списке «Посмотреть, потестить», но никак руки не доходят.
ULOG можно заменить ipt_netflow. Неплохую разгрузку получите.
Давненько я не видел таких дельных статей! Автор — молодец! Спасибо за статью!
Если сервер работает только маршрутизатором, то тюнинг TCP стека особого значения не имеет. Однако есть параметры sysctl, которые позволяют увеличить размер кэша ARP, что может быть актуальным. Например:
net.ipv4.neigh.default.gc_thresh1 = 1024
net.ipv4.neigh.default.gc_thresh2 = 2048
net.ipv4.neigh.default.gc_thresh3 = 4096

Описания параметров добавлю в статью.
боюсь, что это преждевременная оптимизация опять. твикать ненагруженные узлы — только закапывать ошибки на будущее.
Да, в комментах это не указал, но в статье написал. Увеличивать кэш ARP стоит только тогда, когда столкнетесь с сообщение в dmesg: «Neighbour table overflow».
Эти параметры рекомендовано делать 1x, 4x и 8x
если нет необходимости в conntrack его тоже надо отрубить
*raw
-A PREROUTING -j NOTRACK
COMMIT

увеличить очередь
ifconfig eth0 txqueuelen 10000

потом смотреть ошибки и по необходимости увеличить буфер
ethtool -G eth0 rx 1024

если надо conntrack то увеличивать
net.ipv4.netfilter.ip_conntrack_max и /sys/module/ip_conntrack/parameters/hashsize
и уменьшать интервалы
net.ipv4.netfilter.ip_conntrack_icmp_timeout
net.ipv4.netfilter.ip_conntrack_udp_timeout_stream
net.ipv4.netfilter.ip_conntrack_udp_timeout
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait
net.ipv4.netfilter.ip_conntrack_tcp_timeout_last_ack
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established
net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_recv
net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_sent

уменьшать количество правил iptables, если надо много однотипных списков то использовать ipset

и пр. пр. пр.
вообще прерывания неплохо автоматом раскидываются таким скриптиком


ncpus=`grep -ciw ^processor /proc/cpuinfo`
test "$ncpus" -gt 1 || exit 1

n=0
for irq in `cat /proc/interrupts | grep eth | awk '{print $1}' | sed s/\://g`
do
    f="/proc/irq/$irq/smp_affinity"
    test -r "$f" || continue
    cpu=$[$ncpus - ($n % $ncpus) - 1]
    if [ $cpu -ge 0 ]
            then
                mask=`printf %x $[2 ** $cpu]`
                echo "Assign SMP affinity: eth$n, irq $irq, cpu $cpu, mask 0x$mask"
                echo "$mask" > "$f"
                let n+=1
    fi
done


>Нужно раскидать прерывания по процессорам. Чтобы это сделать нужно выполнить команду echo N > /proc/irq/X/smp_affinity

По-моему, раскидывать вручную — лишнее. Есть irqbalance (http://www.irqbalance.org). И в ядре, вроде, есть встроеный балансировщик (CONFIG_IRQBALABCE)
irqbalance при большой нагрузке и большом кол-ве очередей сносит мозг :)
Преимущество ручного раскидывания — группировка определенных очередей на одном ядре.
А когда на одном из серверов использовал irqbalance — неоднократные кернел паники, после чего он был отключен.
Опция CONFIG_IRQBALANCE отсутствует начиная с версии 2.6.27, т.к. признана устаревшей.
Кстати про тюнинг параметров драйверов Вы тоже ни слова не написали, а тема очень обширна :)
А что посоветуете если в iptables большое количество записей >50k в этом случае оно медленно, но верное умирает.
Ну кроме перехода на ipset :) возможно есть какие-нибудь твики?
Распределение прерываний по ядрам поможет и в этом случае. Еще стоит оптимизировать правила с использованием ветвлений.
По поводу тюнинга параметров сетевого драйвера. Я сегодня работал с e1000, удалось сократить с 39K interrupts при дефолтовых настройках до 220 параметром InterruptThrottleRate=100

rmmod e1000
modprobe e1000
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
1 0 0 3680984 48968 35420 0 0 0 7 39964 35 0 1 99 0
0 0 0 3680984 48968 35420 0 0 0 0 39954 33 0 1 99 0

rmmod e1000
modprobe e1000 InterruptThrottleRate=100
0 0 0 3668768 49288 38696 0 0 0 0 220 35 0 0 100 0
0 0 0 3668768 49288 38696 0 0 0 0 224 41 0 0 100 0

Параметры e1000: www.intel.com/support/network/sb/CS-009209.htm
Параметр InterruptThrottleRate (если значение >100) задает количество прерываний, генерируемых в секунду. Эффект аналогичен заданию значений rx-usecs tx-usecs утилитой ethtool, что является более гибким вариантом, поэтому этот параметр e1000 не описывал. Задержки между прерываниями позволяют снизить нагрузку за счет увеличения задержек обработки трафика. Я рекомендую снижать их как можно сильнее, вплоть до ноля, пока нагрузка в часы пик будет в пределах нормы. Соответственно параметр InterruptThrottleRate повышать, пока нагрузка в пределах нормы.
«тюнинг TCP стека особого значения не имеет. Однако есть параметры sysctl, которые позволяют увеличить размер кэша ARP»

Кэш ARP не относится к тюнингу TCP-стека
В фразе подразумевался смысл «тюнинг TCP стека особого значения не имеет, однако имеет значение тюнинг ARP кэша». Пожалуй фразу мне следовало построить по-другому. В любом случае, спасибо за замечание :)
Не очень понял «Чем больше значение, тем выше задержка, но тем меньше нагрузка на процессор. Пробуйте уменьшать это значение в часы пик вплоть до ноля.» Если так, то уменьшение значения в часы пик приведёт к дополнительному росту нагрузки на процессор ведь?
Сейчас обнаружил интересный момент:
root@ххх:/proc/irq# echo 100000000 > 109/smp_affinity
-bash: echo: write error: Value too large for defined data type

Система не дает повесить прерывание на ядро > 31
В итоге повесил 9 прерываний от сетевой карты на 4 ядра. Тем не менее это дало прирост на сетевой карте +100 МБ/с на прием. В итоге из 10Гб карты мы выжали 1100ГБ/с вполне себе боевых данных, которые льются на машину.
Бешеный прирост производительности дали настройки дискового кэша — он непрерывно сбрасывается сейчас, а не ждет в памяти до победного, тормозя сетевую передачу во время сбрасывания данных.
dstat выглядит вот так:
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
15 12 70 0 0 2| 17M 1380M|1109M 28M| 0 0 | 469k 847k
15 12 70 0 0 3| 16M 1669M|1116M 28M| 0 0 | 481k 868k
14 12 72 0 0 2|8924k 1374M| 998M 25M| 0 0 | 438k 766k
15 13 69 0 0 3| 23M 1672M|1130M 28M| 0 0 | 482k 822k
15 12 70 0 0 3| 16M 1542M|1119M 28M| 0 0 | 482k 869k
15 13 69 0 0 3| 20M 1521M|1121M 28M| 0 0 | 483k 894k
15 12 70 0 0 3| 15M 1647M|1130M 28M| 0 0 | 482k 897k
15 12 71 1 0 2| 18M 1356M|1357M 34M| 0 0 | 477k 857k
15 13 69 0 0 2|8596k 1524M|1118M 28M| 0 0 | 478k 920k
15 12 70 0 0 3| 12M 1642M|1112M 28M| 0 0 | 479k 873k
15 12 70 0 0 2| 24M 1384M|1119M 28M| 0 0 | 473k 898k
15 13 70 0 0 3| 22M 1610M|1113M 28M| 0 0 | 477k 930k
15 12 70 0 0 2| 18M 1406M|1114M 28M| 0 0 | 472k 929k


Подскажите, какой язык надо выбирать, чтобы нормально отображался моноширинный текст?
Забыл сразу отписать. Таки позволяет, но немного другим способом:
echo 000001,00000000 > 109/smp_affinity
Sign up to leave a comment.

Articles