Jump to content
Калькуляторы

Linux NAT оптимизация для 10G+ трафика

Добрый день!

Есть текущая NAT-молотилка:

Linux nat 2.6.32-358.23.2.el6.x86_64 #1 SMP Wed Oct 16 18:37:12 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

Intel® Xeon® CPU E3-1270 V2 @ 3.50GHz

с сетевухой Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection на 2 порта.

На текущий момент используется один порт

Драйвер ixgbe-3.17.3

 

в sysctl.conf подкрутил:

# NAT optimization

net.netfilter.nf_conntrack_max = 1572864

net.netfilter.nf_conntrack_generic_timeout = 300

net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 60

net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60

net.netfilter.nf_conntrack_tcp_timeout_established = 600

net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 60

net.netfilter.nf_conntrack_tcp_timeout_close_wait = 45

net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30

net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120

net.netfilter.nf_conntrack_tcp_timeout_close = 10

net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300

net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300

net.netfilter.nf_conntrack_udp_timeout = 30

net.netfilter.nf_conntrack_udp_timeout_stream = 60

net.netfilter.nf_conntrack_icmpv6_timeout = 30

net.netfilter.nf_conntrack_icmp_timeout = 30

net.netfilter.nf_conntrack_events_retry_timeout = 15

net.netfilter.nf_conntrack_checksum=0

net.core.dev_weight = 16

net.core.netdev_budget = 256

net.core.netdev_max_backlog = 16000

 

в modprobe.d добавил nf_conntrack.conf

options nf_conntrack hashsize=524288

 

в rc.local прибил прерывания от очередей к ядрам

echo 1 > /proc/irq/36/smp_affinity

echo 2 > /proc/irq/37/smp_affinity

echo 4 > /proc/irq/38/smp_affinity

echo 8 > /proc/irq/39/smp_affinity

 

ну и в опциях интерфейса ifcfg-eth2:

ETHTOOL_OPTS="-G eth2 rx 2048 tx 2048; -A eth2 autoneg off rx off tx off"

 

сейчас в ЧНН жует 7.5Gbit/s 950Kpps, CPU 60% равномерно по всем ядрам.

Трафик duplex, серые и белые разведены вланами

 

В связи с увеличением пулов серых адресов, увеличивается трафик. Думаю подкинуть второй 10G интерфейс.

И вот тут возникают вопросы:

1. Куда прибивать прерывания - проц 4х ядерный, 4 очереди на первом порту уже есть. Что будет лучше - сделать по 2 очереди на каждый порт или так и оставить по 4?

2. Поскольку делаю нат /25 серой сети в один белый ip, таблица nat в iptables растет с увеличением пулов. Сейчас правила вида -A POSTROUTING -s 172.28.16.0/25 -o vlan28 -j SNAT --to-source 62.122.х.х - отдельной строчкой для каждой /25 сети. Можно ли как-то это оптимизировать?

3. Начитался здесь же, что слишком большой hashsize не всегда даёт выигрыш. Соответственно посоветуйте, стоит ли уменьшить в моем случае? nf_conntrack_count в ЧНН примерно 1200 тыс.

4. И раз уж говорим о том, что таблица hash'ей не влезает или вычищается из кэша проца, то имеет смысл обсудить и возможность уменьшения context switching для ядер. Хотя, я не представляю пока, как это можно сделать настройками. Может кто-то занимался этим вопросом и может подсказать?

Share this post


Link to post
Share on other sites

Вопрос не простой, попробую дать свое видиние.

 

1. Вы не сможете сместить весь 7.5Гб на 2 ядра, т.к. в этом случае каждое ядро будет нагружено на 120%. Соответственно ваш путь - это назначать прерывания на те же ядра. Это даст оверхед при переключениях контекста, но даст возможность принять больше трафика. При трафике на втором порту, у вас будет примерно 70% занятости на каждое ядро, вместо 60%. Вообще, при 70% загрузке, я бы рекомендовал начинать разнос нагрузки на еще одну железку. Ну или апгрейдить эту.

2. Если белые адреса ната пересекаются для разных подсетей /25, то можно агреггировать в цепочки. Но вообще, я не думаю, что данная оптимизация что-то даст. Сколько у вас таких правил, штук 10? Посмотрите в профайлере общий вклад фильтра iptables, я думаю, что он будет 1-2% максимум.

3. hashsize как и, например размер ring buffer, который у вас 2048 - чем меньше, тем лучше, потому что быстрее. Но чем меньше, тем выше возможность в ЧНН начать терять пакеты ( ring buffer ), либо соединения ( hashsize ). Вообще hashsize зависит от conntrack_max в виде hashsize = conntrack_max/8. В вашем случае это = 196608. Ни больше, ни меньше его ставить не надо. У вас больше чем надо.

4. Таблица соединений не попадает в кеш процессора ( возможно разве что частично ), а находится обычно в ОЗУ, т.к. слишком большая и операции над ней происходят на более высоком уровне ОС, а не на уровне драйверов, например. Уменьшить количество csw можно уменьшив количество прерываний. Но это опять игра в баланс. Уменьшая количество прерываний вы рискуете в случае всплеска трафика не успевать всё выгребать из буферов карт - будет потеря пакетов.

 

В целом, я хочу сказать, что 10 Гбит на 4 ядра такого процессора как ваш, это хороший результат для НАТа ( будет 90% нагрузка где-то ). Возможно, вам удасться что-то подкрутить и засунуть туда, 11 Гбит, но по-моему это не имеет смысла, т.к. рисковано. Если хотите 20 Гбит - надо 8 ядер. Кстати, еще важна скорость ОЗУ. Вы её не указали, а это не менее важный параметр, нежели скорость проца. Но опять таки, судя по достигнутым результатам со скоростью ОЗУ всё нормально.

Edited by Dark_Angel

Share this post


Link to post
Share on other sites

hashsize как и, например размер ring buffer, который у вас 2048 - чем меньше, тем лучше, потому что быстрее. Но чем меньше, тем выше возможность в ЧНН начать терять пакеты ( ring buffer ), либо соединения ( hashsize ). Вообще hashsize зависит от conntrack_max в виде hashsize = conntrack_max/8. В вашем случае это = 196608. Ни больше, ни меньше его ставить не надо. У вас больше чем надо.

Бред по обеим пунктам.

ring buffer - чем он больше, тем реже можно вызывать прерывания, тем меньше переключений контекста.

hash size - не зависит от conntrack_max. Вообще. Ибо представляет собой хэш для ускоренного поиска записей коннтрака, и можно его поставить хоть равным 16, хоть равным conntrack_max. А вот среднее кол-во операций сравнения в наихудшем случае для поиска записи в таблице = conntrack_max/hash_size. Из чего и плясать - разницы между 8 и 16 операциями сравнения скорее всего не будет видно, а вот между 1024 и 2048 - скорее всего будет вполне заметна. + рекомендуется хэш делать относительно небольшим, чтобы не вымывался из кэша проца.

 

Если хотите 20 Гбит - надо 8 ядер.

А с чего вы взяли, что 8 ядер промолотят в 2 раза больше траффика/сессий, чем 4 ядра? :)

Share this post


Link to post
Share on other sites

Бред по обеим пунктам.

ring buffer - чем он больше, тем реже можно вызывать прерывания, тем меньше переключений контекста.

 

Если все так просто, то зачем тогда дефолтный буфер установлен в 512? Ставили бы стразу в 4096. А все потому что ваше утверждение ложно. Чем меньше буфер, тем меньше будет cache_miss при прерывании. В теме про софтроутер эта тема обсуждалась, с участием ядерного кота. Почитайте.

 

Поэтому буфер нужно держать не максимальным, а поближе к заполненности, тогда это будет наиболее еффективно.

 

Ну и да, чем больше буфер, тем реже можно звать прерывания, но одно дело обработать прерывания и достать из буфера 500 пакетов, а другое 4000.

 

Моя практика показывает, что разница в производительности может достигать 10% между минимальным размером буфера и максимальным. На одинаковом трафике.

 

hash size - не зависит от conntrack_max. Вообще. Ибо представляет собой хэш для ускоренного поиска записей коннтрака, и можно его поставить хоть равным 16, хоть равным conntrack_max. А вот среднее кол-во операций сравнения в наихудшем случае для поиска записи в таблице = conntrack_max/hash_size. Из чего и плясать - разницы между 8 и 16 операциями сравнения скорее всего не будет видно, а вот между 1024 и 2048 - скорее всего будет вполне заметна. + рекомендуется хэш делать относительно небольшим, чтобы не вымывался из кэша проца.

 

Конечно зависит. Поставьте 16, и 1.5М соединений потрекать, и посмотрим что будет. Будет куча коллизий хеша и всё будет плохо. Кроме того, в LARTC написано ставить его кратным conntrack_max именно по приведенной выше формуле. Почему вы считате, что рекомендация в LARTC туфта и сколько вы предлагаете поставить в текущем случае и что это даст? Мне правда интересно.

 

А с чего вы взяли, что 8 ядер промолотят в 2 раза больше траффика/сессий, чем 4 ядра? :)

 

Из личного опыта. Мне не удавалось настроить машину так, чтобы обработать 2Mpps реального трафика под НАТом на 4х ядрах. 10Г или 1.2-1.3Mpps - это разумный потолок для такой машины.

Edited by Dark_Angel

Share this post


Link to post
Share on other sites

2. Поскольку делаю нат /25 серой сети в один белый ip, таблица nat в iptables растет с увеличением пулов. Сейчас правила вида -A POSTROUTING -s 172.28.16.0/25 -o vlan28 -j SNAT --to-source 62.122.х.х - отдельной строчкой для каждой /25 сети. Можно ли как-то это оптимизировать?

Есть опыт по данному моменту:

НАТим приватную /24, в один публичный /32, раньше были просто линейные правила типа ваших, вплоть до 400 сравнений подрят.

10.0.0.0/24 -o eth1 -j SNAT --to-source 178.XXX.0.1

10.0.1.0/24 -o eth1 -j SNAT --to-source 178.XXX.0.2

10.0.2.0/24 -o eth1 -j SNAT --to-source 178.XXX.0.3

и тд.

 

Для повышения производительности перевели это на механизм бинарного дерева.

 

То есть делаем одну проверку -> совпало, перекидываем в нижестоящую табличку. Не совпало, продолжаем в этой, и считаем что табличка уже более узкая.

Логически это выглядит следующим образом.

Match /16 -> match /17 -> match /18.... match /24 -> SNAT

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

в двух словах вот так:

 

-A nat-10.198.168.0/21 -s 10.198.168.0/22 -j nat-10.198.168.0/22
-A nat-10.198.168.0/21 -s 10.198.172.0/22 -j nat-10.198.172.0/22

-A nat-10.198.168.0/22 -s 10.198.168.0/23 -j nat-10.198.168.0/23
-A nat-10.198.168.0/22 -s 10.198.170.0/23 -j nat-10.198.170.0/23

-A nat-10.198.168.0/23 -s 10.198.168.0/24 -j SNAT --to-source 178.XXX.41.172
-A nat-10.198.168.0/23 -s 10.198.169.0/24 -j SNAT --to-source 178.XXX.41.173

 

Таким образом пакет будучи определем с точностью до /16 проходит всего 8 проверок, вместо 400/2

Профит от внедрения был 2-3% CPU, и сделав абсолютно нечитаемым конфиг IPTABLES :)

Но, откатывать изменение таки не стали

 

Сервер E5-1660v2, трафика 15Gb/s IN+OUT, 2Mpps, NAT+Netflow

Share this post


Link to post
Share on other sites

Юра забыл упомянуть, что алгоритм несколько более хитрый, и в цепочке /16 - /17 - /18 ... /24 пропускает "лишние" шаги.

К примеру, если у нас 2 /24, к примеру 10.1.0.0/24 и 10.1.1.0/24 - цепочка сократится до /16 -> /23 -> /24.

 

Т.е. шаги в которых должен быть только один вариант выбора (10.0.0.0/16 -> 10.0.0.0/17 -> 10.0.0.0/18 и т.п., вплоть до "разветвления" в 10.0.0.0/23) выкидываются как бессмысленные.

 

Ну и дерево - не бинарное :))

Share this post


Link to post
Share on other sites

Спасибо, что откликнулись. Поскольку тут уже пошли дебаты, хочу высказать так же свои мысли. Поправьте меня, если я в чем-то неправ.

1. Я так понял, что ожидать 70% нагрузки на ядра стоит при таком же трафике (7.5 гбит), но раскинутом на 2 интерфейса? Тогда действительно, смысла во втором интерфейсе нет, так как суммарно протянет не многим более 10Гбит, а еще один порт 10G займет. Апгрейдить это железо уже некуда, Xeon E3 более 4 ядер не бывает, а по частоте максимальный 3.7 против моих 3.5 - не думаю, что будет существенная разница.

2. Правил сейчас уже порядка 180, а если расширять - то будет еще больше. При текущей нагрузке (~33% на ядрах) в perf top видим ip_route_input порядка 10%, ipt_do_table - около 2%. еще в ЧНН посмотрю. Но даже если там 5% - не хотелось бы их просто так "терять". Каким образом можно собирать в цепочки? у меня правила вида

-A POSTROUTING -s 172.28.16.0/25 -o vlan28 -j SNAT --to-source 62.aa.bb.cc

-A POSTROUTING -s 172.28.16.128/25 -o vlan28 -j SNAT --to-source 62.aa.bb.cc+1

-A POSTROUTING -s 172.28.17.0/25 -o vlan28 -j SNAT --to-source 62.aa.bb.cc+2

-A POSTROUTING -s 172.28.17.128/25 -o vlan28 -j SNAT --to-source 62.aa.bb.cc+3

3. Понял, что больше. Но с учетом того, что траффик будет ползти вверх из-за количества пользователей, то и общее количество трансляций вырастет, значит надо будет поставить с запасом при увеличении conntrack_max

4. По поводу памяти - там стоит DDR3 ECC PC3-12800 2 планки по 4 гига. CAS Latency не помню. Поскольку таблица не умещается в кэши L1 и L2, но вероятно может поместиться в кэш L3 возникает вопрос - а при csw содержимое L3 по идее не должно перезаполняться, ведь он shared между ядрами. Или я тут совсем неправ?

 

Теперь по поводу смены железа и 8 ядер. Поскольку Е3 не может участвовать в мультипроцессорных системах (имеются ввиду физические процессоры), а ядер у топовых только 4, то возникает необходимость уходить хотя бы на Е5. И вот тут вопрос - насколько критична частота ядер в данной задаче? Ведь если я всё правильно понимаю, то чем выше частота, тем больше теоретически прерываний в секунду можно обработать. Если чисто гипотетически предположить, что обработка одного прерывания занимает у нас один цикл процессорного времени, то тогда процессоры с частотой в 2Ггц могут обработать 2 млрд прерываний (на ядро), а вот процессоры с частотой в 3.5Ггц - соответственно 3.5 млрд. Вот и возникает вопрос - лучше взять два процессора Е5 4 ядра с частотой в 2.0 ггц или один на 6 ядер, но 2.5 Ггц?

И, кстати, насколько будет велика разница между процессорами Е3 и Е5 в данной задаче, при условии одинакового количества ядер и частоты? Это вопрос чисто по поводу архитектуры - насколько заметно изменения в случае задачи NAT?

И вопрос совсем из области фантастики - а никто не пробовал процессоры AMD с 8 ядрами и космической частотой в 4+ГГц для этой задачи?

Share this post


Link to post
Share on other sites

Профит от внедрения был 2-3% CPU, и сделав абсолютно нечитаемым конфиг IPTABLES :)

Но, откатывать изменение таки не стали

 

Сервер E5-1660v2, трафика 15Gb/s IN+OUT, 2Mpps, NAT+Netflow

 

Профит был по 3% на ядро? Нечитаемость конфига для "обычных смертных" не принципиальна.

Посмотрел характеристики процессора - по частоте примерно такой же, по количеству ядер чуть больше. При этом трафика в 2 раза больше, чем у меня. А какая сейчас нагрузка на проце при таком трафике? Это потолок или есть еще запас?

Ну и, если можно, настройки специфичные можете показать? тот же hashsize, ring buffer. может быть что-то еще было?

Share this post


Link to post
Share on other sites

1. Я так понял, что ожидать 70% нагрузки на ядра стоит при таком же трафике (7.5 гбит), но раскинутом на 2 интерфейса? Тогда действительно, смысла во втором интерфейсе нет, так как суммарно протянет не многим более 10Гбит, а еще один порт 10G займет. Апгрейдить это железо уже некуда, Xeon E3 более 4 ядер не бывает, а по частоте максимальный 3.7 против моих 3.5 - не думаю, что будет существенная разница.

 

Все именно так.

 

2. Правил сейчас уже порядка 180, а если расширять - то будет еще больше. При текущей нагрузке (~33% на ядрах) в perf top видим ip_route_input порядка 10%, ipt_do_table - около 2%. еще в ЧНН посмотрю. Но даже если там 5% - не хотелось бы их просто так "терять". Каким образом можно собирать в цепочки? у меня правила вида

-A POSTROUTING -s 172.28.16.0/25 -o vlan28 -j SNAT --to-source 62.aa.bb.cc

-A POSTROUTING -s 172.28.16.128/25 -o vlan28 -j SNAT --to-source 62.aa.bb.cc+1

-A POSTROUTING -s 172.28.17.0/25 -o vlan28 -j SNAT --to-source 62.aa.bb.cc+2

-A POSTROUTING -s 172.28.17.128/25 -o vlan28 -j SNAT --to-source 62.aa.bb.cc+3

 

180 правил достаточно много, но если они все у вас с исходящим интерфейсом, да еще и в построутинге, то они обрабатываются достаточно быстро. Не думаю, что удасться оптимизировать без изменения самой схемы адресации.

 

3. Понял, что больше. Но с учетом того, что траффик будет ползти вверх из-за количества пользователей, то и общее количество трансляций вырастет, значит надо будет поставить с запасом при увеличении conntrack_max

 

Ну так и увеличите вместе с conntrack_max. Зачем держать запас?

 

4. По поводу памяти - там стоит DDR3 ECC PC3-12800 2 планки по 4 гига. CAS Latency не помню. Поскольку таблица не умещается в кэши L1 и L2, но вероятно может поместиться в кэш L3 возникает вопрос - а при csw содержимое L3 по идее не должно перезаполняться, ведь он shared между ядрами. Или я тут совсем неправ?

 

У вас кеш пошарен с L2. Intel Smart Cache же. Я не уверен, впрочем, что он сбрасывается полностью. Уже не говоря о L3. L1 точно сбрасывается, а вот остальные - не знаю. Но в любом случае таблица кусками попадает во все кеши. Целиком она ни в один из них не влезет, т.к. она слишком большая и есть более важные данные, которые нужны процессору прямо сейчас. Зато она точно находится в ОЗУ. Вся и целиком. И оттуда выгружается в кеши при надобности.

 

Теперь по поводу смены железа и 8 ядер. Поскольку Е3 не может участвовать в мультипроцессорных системах (имеются ввиду физические процессоры), а ядер у топовых только 4, то возникает необходимость уходить хотя бы на Е5. И вот тут вопрос - насколько критична частота ядер в данной задаче? Ведь если я всё правильно понимаю, то чем выше частота, тем больше теоретически прерываний в секунду можно обработать. Если чисто гипотетически предположить, что обработка одного прерывания занимает у нас один цикл процессорного времени, то тогда процессоры с частотой в 2Ггц могут обработать 2 млрд прерываний (на ядро), а вот процессоры с частотой в 3.5Ггц - соответственно 3.5 млрд. Вот и возникает вопрос - лучше взять два процессора Е5 4 ядра с частотой в 2.0 ггц или один на 6 ядер, но 2.5 Ггц?

И, кстати, насколько будет велика разница между процессорами Е3 и Е5 в данной задаче, при условии одинакового количества ядер и частоты? Это вопрос чисто по поводу архитектуры - насколько заметно изменения в случае задачи NAT?

И вопрос совсем из области фантастики - а никто не пробовал процессоры AMD с 8 ядрами и космической частотой в 4+ГГц для этой задачи?

 

Частота напрямую влияет на пропускную способность роутера. Поэтому чем больше частота, тем лучше. По количеству прерываний вы ошиблись на несколько порядков. Прерывание занимает больше времени чем один такт процессора. По факту, я не думаю, что современный драйвер вам даст выполнить более 100К прерываний на очередь. Да и не нужно столько.

 

Поэтому да, вам нужно смотреть на E5, два процессора и чтобы камни были побыстрее. И память тоже побыстрее. Мамки с быстрой памятью стоят немного дороже.

 

Если так хочется 20 Гбит, попробуйте i7 с 6ю ядрами. Там и кеша больше и вообще разогнать можно. Короче 20 Гбит реально пропихнуть. 2.5-2.7 Mpps. Но я бы лучше поставил вторую железку рядом.

 

АМД я пробовал, но там не было такого трафика. В целом, АМД показали себя не плохо ( 2 процовая система ), но когда я последний раз искал железо, у меня получилось, что AMD будет стоить в 1.5 раза дороже сервера на Intel. Уж не знаю как так получилось. Поэтому пока на АМД не смотрю. Да и зачем, если на Интеле всё отлично работает и стоит нормально?

Edited by Dark_Angel

Share this post


Link to post
Share on other sites

Поставьте 16, и 1.5М соединений потрекать, и посмотрим что будет. Будет куча коллизий хеша и всё будет плохо.

Поставьте 1.5М хэш, посмотрим что будет :) Куча cache misses и все плохо. Хотя коллизий не будет совсем :)

 

Кроме того, в LARTC написано ставить его кратным conntrack_max именно по приведенной выше формуле. Почему вы считате, что рекомендация в LARTC туфта и сколько вы предлагаете поставить в текущем случае и что это даст?

LARTC никоим образом не учитывает размер кеша проца. А по хорошему хеш должен сидеть в кеше для оптимального быстродействия (лучше - в л2 если будет жить, но как минимум - не вымываться из л3).

 

Из личного опыта. Мне не удавалось настроить машину так, чтобы обработать 2Mpps реального трафика под НАТом на 4х ядрах. 10Г или 1.2-1.3Mpps - это разумный потолок для такой машины.

Вопрос стоял именно в 2-кратном приросте производительности при 2-кратном увеличении кол-ва ядер. Потому как реально там будет совсем не в 2 раза рост. И от того вполне возможно, что 2 мелких тазика окажутся более предпочтительными, чем 1 монстр. И по цене, и по производительности, и по надежности (ибо резерв).

 

И вопрос совсем из области фантастики - а никто не пробовал процессоры AMD с 8 ядрами и космической частотой в 4+ГГц для этой задачи?

Медленная подсистема памяти сливает все прелести ядер.

Share this post


Link to post
Share on other sites

 

Просмотр сообщенияjunjunk2 (Вчера, 17:53) писал:

И вопрос совсем из области фантастики - а никто не пробовал процессоры AMD с 8 ядрами и космической частотой в 4+ГГц для этой задачи?

 

Медленная подсистема памяти сливает все прелести ядер.

Понятно. В принципе я примерно это и предполагал, но хотел уточнить реальный опыт.

 

Поскольку разразилось активное сражение по поводу размера hashsize, есть предложение провести эксперимент. Сейчас имеются практически одинаковые 2 машинки, как я указывал в начале топика. Я за сегодня постараюсь привести специально таблицу маршрутизации обеих машинок к одному виду (+/- 1 маршрут). Трафика на них будет практически одинаково - около 6.5-7 ГБит/с. Трансляций тоже примерно одинаково, настройки максимального количества - 100% одинаковые. Соответственно на одной машине я поставлю hashsize равным 196608, как рекомендует Dark_Angel, а на другой - 65536 (как я понял из советов NiTr0, уменьшение вероятности вымывания таблицы хэшей из кэша процессора. могу поставить другое значение по пожеланию NiTr0). Посмотрим, что с какой машиной будет твориться. Кстати, подскажите, что именно в этом случае мониторить и каким способом? это чтобы все увидели всю интересующую статистику.

Share this post


Link to post
Share on other sites

Мониторить pps, кол-во записей коннтрака и загрузку ядер. Если первое и второе примерно одинаковы - значит, машины в идентичных условиях.

Для чистоты эксперимента потом можно будет поменять клиентов между машинами ночью, и провести повторный тест :)

Share this post


Link to post
Share on other sites

Профит от внедрения был 2-3% CPU, и сделав абсолютно нечитаемым конфиг IPTABLES :)

Но, откатывать изменение таки не стали

 

Сервер E5-1660v2, трафика 15Gb/s IN+OUT, 2Mpps, NAT+Netflow

 

Профит был по 3% на ядро? Нечитаемость конфига для "обычных смертных" не принципиальна.

Посмотрел характеристики процессора - по частоте примерно такой же, по количеству ядер чуть больше. При этом трафика в 2 раза больше, чем у меня. А какая сейчас нагрузка на проце при таком трафике? Это потолок или есть еще запас?

Ну и, если можно, настройки специфичные можете показать? тот же hashsize, ring buffer. может быть что-то еще было?

 

Да, профит был по 3% на ядро.

Загрузка проца сейчас 80%, но это без Netflow, по прикидкам Netflow добавляет +5-7%, так что можно сказать что это предел.

По тюнингу:

 

RX/TX ring на 2048

Если выкрутить на 4096, были дропы rx_nodma_resource

rx-usecs: 500

С адаптивным управлением прерываний были rx_missed_errors не в ЧНН

 

conntrack_max=4194304

В реалиях там 3.3М в ЧНН

 

ну и что самое интересное...

cat /sys/module/nf_conntrack/parameters/hashsize

33554432

 

Так что на ваш вечерний эксперимент с удовольствием посмотрим :)

Share this post


Link to post
Share on other sites

Итак, еще не совсем ЧНН, но разница заметна уже сейчас. После графиков краткое описание состояния машин.

d0b8edd74188ba0d0079d8cf2408e00b.png

adf714eee66e43210c281f1392c67b6e.png

058c55740e9f619755441769deb3d20b.png

24b15b7f4d12e2329e1ca0cc8e4272f9.png

 

Как видно из картинок, на машине nat2 трафика меньше на ~1 Гбит/с, pps меньше примерно на 100тыс, conntracks тоже на 90 тыс меньше, однако нагрузка на ней выше на 3-4%. Напомню, что по железу, ОС и настройкам, кроме conntracks hashsize машины идентичны.

А вот разница:

 

[root@nat ~]# sysctl net.netfilter.nf_conntrack_buckets
net.netfilter.nf_conntrack_buckets = 196608

[root@nat2 ~]# sysctl net.netfilter.nf_conntrack_buckets
net.netfilter.nf_conntrack_buckets = 65536

 

ну и perf top вот что показывает в это время:

nat2:
22.42%  [kernel]            [k] __nf_conntrack_find
 9.96%  [kernel]            [k] ip_route_input
 4.83%  [kernel]            [k] ixgbe_poll
 3.90%  [kernel]            [k] _spin_lock
 2.79%  [kernel]            [k] nf_conntrack_tuple_taken
 2.28%  [kernel]            [k] dev_queue_xmit
 2.01%  [kernel]            [k] eth_type_trans
 1.66%  [kernel]            [k] ipt_do_table

nat:
12.08%  [kernel]             [k] ip_route_input
12.04%  [kernel]             [k] __nf_conntrack_find
 4.92%  [kernel]             [k] ixgbe_poll
 4.45%  [kernel]             [k] _spin_lock
 2.16%  [kernel]             [k] dev_queue_xmit
 2.09%  [kernel]             [k] eth_type_trans
 1.80%  [kernel]             [k] tcp_packet
 1.75%  [kernel]             [k] vlan_gro_common
 1.70%  [kernel]             [k] ipt_do_table
 1.69%  [kernel]             [k] ixgbe_xmit_frame_ring

 

Кстати, вот тут по ходу дела у меня возникли 2 вопроса.

1. Почему такая разница в занимаемом времени времени у ip_route_input? Таблицу маршрутизации сделал абсолютно одинаковой, на одной машинке даже пришлось специально поднять еще один vlan интерфейс.

2. Очень большая разница в context switch на машинах. Не могу понять, откуда это идет?

[root@nat2 ~]# dstat --time --all
----system---- ----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
 date/time   |usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw
15-11 21:01:03|  0   0  60   0   0  40|   0     0 |1298M 1305M|   0     0 |  35k  568
15-11 21:01:04|  0   0  61   0   0  39|   0     0 |1299M 1307M|   0     0 |  35k  765
15-11 21:01:05|  0   0  60   0   0  40|   0     0 |1317M 1325M|   0     0 |  35k 1196
15-11 21:01:06|  0   0  52   0   0  48|   0     0 |1347M 1354M|   0     0 |  35k 4332
15-11 21:01:07|  0   0  55   0   0  45|   0  5120B|1328M 1336M|   0     0 |  35k 3904
15-11 21:01:08|  0   0  54   1   0  44|   0    65k|1292M 1299M|   0     0 |  35k 4777
15-11 21:01:09|  0   1  53   0   0  47|   0     0 |1319M 1326M|   0     0 |  34k 4341
15-11 21:01:10|  0   0  51   0   0  49|   0     0 |1399M 1407M|   0     0 |  34k 4369
15-11 21:01:11|  0   0  53   0   0  46|   0     0 |1400M 1407M|   0     0 |  35k 3460
15-11 21:01:12|  0   0  53   0   0  47|   0     0 |1376M 1384M|   0     0 |  35k 3919
15-11 21:01:13|  0   0  52   0   0  48|   0  5120B|1372M 1380M|   0     0 |  34k 3780
15-11 21:01:14|  0   1  53   0   0  46|   0     0 |1281M 1288M|   0     0 |  34k 3999
15-11 21:01:15|  0   0  53   0   0  47|   0     0 |1306M 1313M|   0     0 |  35k 4239
15-11 21:01:16|  0   0  54   0   0  45|   0     0 |1285M 1292M|   0     0 |  35k 3240
15-11 21:01:17|  0   0  53   0   0  46|   0     0 |1336M 1344M|   0     0 |  35k 3355
15-11 21:01:18|  0   0  53   0   0  47|   0     0 |1296M 1303M|   0     0 |  34k 3443
15-11 21:01:19|  0   1  52   0   0  47|   0     0 |1354M 1362M|   0     0 |  34k 3865
15-11 21:01:20|  0   0  54   0   0  46|   0     0 |1381M 1389M|   0     0 |  35k 3391
15-11 21:01:21|  0   0  52   0   0  48|   0     0 |1391M 1399M|   0     0 |  34k 4057
15-11 21:01:22|  0   0  52   0   0  47|   0     0 |1337M 1345M|   0     0 |  34k 4177
15-11 21:01:23|  0   0  51   0   0  48|   0  5120B|1387M 1394M|   0     0 |  34k 3631
15-11 21:01:24|  0   0  53   0   0  47|   0     0 |1331M 1338M|   0     0 |  34k 3870
15-11 21:01:25|  0   0  53   0   0  47|   0     0 |1356M 1364M|   0     0 |  34k 3873
15-11 21:01:26|  0   0  52   0   0  48|   0     0 |1357M 1365M|   0     0 |  34k 3759
15-11 21:01:27|  0   0  51   0   0  49|   0     0 |1386M 1394M|   0     0 |  34k 3601
15-11 21:01:28|  0   0  52   0   0  47|   0     0 |1390M 1398M|   0     0 |  34k 3734
15-11 21:01:29|  0   0  53   0   0  47|   0     0 |1350M 1358M|   0     0 |  34k 3971
15-11 21:01:30|  0   0  51   0   0  48|   0     0 |1394M 1402M|   0     0 |  34k 4248
15-11 21:01:31|  0   0  50   0   0  49|   0     0 |1451M 1459M|   0     0 |  34k 3774
15-11 21:01:32|  0   0  51   0   0  49|   0     0 |1428M 1436M|   0     0 |  34k 3434
15-11 21:01:33|  0   0  51   0   0  49|   0     0 |1386M 1394M|   0     0 |  34k 3964
15-11 21:01:34|  0   0  51   0   0  49|   0     0 |1364M 1372M|   0     0 |  34k 3591
15-11 21:01:35|  0   0  51   0   0  49|   0     0 |1401M 1409M|   0     0 |  34k 3618
15-11 21:01:36|  0   0  51   0   0  49|   0    56k|1349M 1357M|   0     0 |  34k 3603
15-11 21:01:37|  0   0  52   0   0  48|   0  6144B|1358M 1365M|   0     0 |  34k 3497
15-11 21:01:38|  0   0  50   0   0  49|   0     0 |1452M 1460M|   0     0 |  34k 3704
15-11 21:01:39|  0   0  51   0   0  49|   0     0 |1452M 1460M|   0     0 |  34k 3157
15-11 21:01:40|  0   0  51   0   0  49|   0     0 |1446M 1454M|   0     0 |  34k 3319
15-11 21:01:41|  0   0  51   0   0  49|   0     0 |1448M 1456M|   0     0 |  34k 3148
15-11 21:01:42|  0   0  49   0   0  51|   0  5120B|1433M 1441M|   0     0 |  34k 3158
15-11 21:01:43|  0   0  49   0   0  50|   0     0 |1425M 1433M|   0     0 |  34k 3367
15-11 21:01:44|  0   0  50   0   0  49|   0     0 |1360M 1368M|   0     0 |  34k 2934
15-11 21:01:45|  0   0  50   0   0  50|   0     0 |1406M 1414M|   0     0 |  34k 2955

[root@nat ~]# dstat --time --all
----system---- ----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
 date/time   |usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw
15-11 21:02:39|  0   0  44   0   0  56|   0     0 |1614M 1623M|   0     0 |  34k  105
15-11 21:02:40|  0   0  43   0   0  57|   0     0 |1648M 1658M|   0     0 |  34k  111
15-11 21:02:41|  0   0  44   0   0  56|   0     0 |1591M 1600M|   0     0 |  34k   94
15-11 21:02:42|  0   0  43   0   0  56|   0     0 |1627M 1637M|   0     0 |  34k   70
15-11 21:02:43|  0   0  45   0   0  55|   0     0 |1576M 1585M|   0     0 |  35k   82
15-11 21:02:44|  0   0  46   0   0  54|   0     0 |1603M 1612M|   0     0 |  34k   85
15-11 21:02:45|  0   0  44   0   0  56|   0     0 |1642M 1651M|   0     0 |  34k   71
15-11 21:02:46|  0   0  44   0   0  56|   0     0 |1601M 1611M|   0     0 |  34k  104
15-11 21:02:47|  0   0  43   0   0  56|   0    12k|1635M 1645M|   0     0 |  34k   92
15-11 21:02:48|  0   0  44   0   0  56|   0     0 |1647M 1657M|   0     0 |  34k   78
15-11 21:02:49|  0   0  42   0   0  58|   0     0 |1665M 1675M|   0     0 |  34k   96
15-11 21:02:50|  0   0  42   0   0  57|   0     0 |1643M 1653M|   0     0 |  33k   95
15-11 21:02:51|  0   0  45   0   0  55|   0     0 |1587M 1596M|   0     0 |  34k   86
15-11 21:02:52|  0   0  44   0   0  56|   0     0 |1598M 1608M|   0     0 |  34k   78
15-11 21:02:53|  0   0  43   0   0  57|   0     0 |1633M 1643M|   0     0 |  34k   86
15-11 21:02:54|  0   0  42   0   0  58|   0     0 |1673M 1683M|   0     0 |  34k   88
15-11 21:02:55|  0   0  45   0   0  55|   0     0 |1592M 1602M|   0     0 |  34k   96
15-11 21:02:56|  0   0  43   0   0  57|   0     0 |1624M 1633M|   0     0 |  34k   84
15-11 21:02:57|  0   0  43   0   0  57|   0     0 |1600M 1609M|   0     0 |  34k   80
15-11 21:02:58|  0   0  40   0   0  59|   0     0 |1693M 1703M|   0     0 |  34k   95
15-11 21:02:59|  0   0  43   0   0  57|   0     0 |1634M 1644M|   0     0 |  34k   84
15-11 21:03:00|  0   0  42   0   0  58|   0     0 |1651M 1661M|   0     0 |  34k   94
15-11 21:03:01|  0   0  43   0   0  57|   0     0 |1629M 1638M|   0     0 |  34k  103
15-11 21:03:02|  0   0  43   0   0  56|   0     0 |1648M 1658M|   0     0 |  34k   86
15-11 21:03:03|  0   0  42   0   0  58|   0     0 |1658M 1667M|   0     0 |  34k   88
15-11 21:03:04|  0   0  43   0   0  57|   0     0 |1628M 1637M|   0     0 |  34k   74
15-11 21:03:05|  0   0  43   0   0  57|   0     0 |1698M 1708M|   0     0 |  34k   89
15-11 21:03:06|  0   1  39   0   0  60|   0     0 |1708M 1718M|   0     0 |  33k  114
15-11 21:03:07|  0   1  40   0   0  59|   0     0 |1659M 1669M|   0     0 |  34k  134
15-11 21:03:08|  0   0  43   0   0  57|   0     0 |1655M 1665M|   0     0 |  34k  102
15-11 21:03:09|  0   0  43   0   0  57|   0     0 |1675M 1685M|   0     0 |  34k  105
15-11 21:03:10|  0   0  42   0   0  58|   0     0 |1744M 1754M|   0     0 |  34k  108
15-11 21:03:11|  0   0  43   0   0  57|   0     0 |1648M 1658M|   0     0 |  34k   88
15-11 21:03:12|  0   0  45   0   0  55|   0     0 |1594M 1604M|   0     0 |  34k  113
15-11 21:03:13|  0   0  45   0   0  55|   0     0 |1600M 1610M|   0     0 |  34k  110
15-11 21:03:14|  0   0  44   0   0  55|   0     0 |1578M 1587M|   0     0 |  34k  107
15-11 21:03:15|  0   0  45   0   0  55|   0     0 |1549M 1558M|   0     0 |  34k   95
15-11 21:03:16|  0   0  43   0   0  57|   0     0 |1667M 1677M|   0     0 |  34k  124
15-11 21:03:17|  0   0  43   0   0  57|   0     0 |1652M 1661M|   0     0 |  34k   90
15-11 21:03:18|  0   0  44   0   0  56|   0     0 |1608M 1617M|   0     0 |  34k   84
15-11 21:03:19|  0   0  43   0   0  57|   0     0 |1629M 1638M|   0     0 |  34k  110
15-11 21:03:20|  0   0  41   0   0  58|   0  4096B|1692M 1702M|   0     0 |  34k  104
15-11 21:03:21|  0   0  41   0   0  58|   0     0 |1687M 1697M|   0     0 |  33k   96

 

PS. Показатели dstat --time --all снимал после того, как на машине nat2 увеличил hashsize до 196608. После этого изменения нагрузка резко спала. Чуть позже приложу график, когда он отрисуется нормально, чтобы видна была ступенька

UPD.Как и обещал - график со ступенькой

9fdb9403f01ee0eea569ea180e20bd67.png

 

И первый вопрос отпал сам по себе, когда сделал одинаковой таблицу hash. Это ж процентное соотношение того, чем занимается ядро. Когда оно больше занималось поиском сессий, то и поиск пути был в процентном соотношении меньше. Сейчас всё одинаково.

 

Вывод

Таблица conntrack_buckets не должна быть маленькой. Да, возможно, если она будет очень большая, то она будет вымываться из кэша проца, но таблица размером в 3МБ остается в нем однозначно и работает намного быстрее, чем малого размера. Рекомендация conntrack_max/8 действует отлично.

Edited by junjunk2

Share this post


Link to post
Share on other sites

А больше чем conntrack_max/8 хеш пробовали?

 

Мы руководствовались тем, что коллизии хеша, занимают больше процессорного времени, нежели доставания кеша из RAM. поэтому задача - сделать заполнение >> 1

Share this post


Link to post
Share on other sites

dazgluk

Дальнейшее увеличение hashsize не привело к каким-либо видимым изменениям. Однако, эта проверка была проведена уже на уменьшенной нагрузке, соответственно, завтра в ЧНН проведу еще один эксперимент

 

 

Так же, кажется, получил ответ на вопрос по поводу csw. Увеличение наблюдается на обеих машинках и связано, видимо, с жизнью других приложений на машинах. В частности, есть подозрение, что агент заббикса, используемый для мониторинга, "просыпается" как раз в моменты увеличения csw. Соответственно вопросы сняты.

 

Параллельно почитал другие топики и появились некоторые вопросы, косвенно связанные с увеличением производительности машинок. А именно:

1. Насколько в моём случае изменит ситуацию отключение intel_idle? Я не заметил его активной работы в моей системе, но в других топиках активно с ним борятся для получения максимальной производительности.

2. Что есть kipmi0 ? Этот процесс постоянно вылазит в dstat --top-cpu. Его вклад крайне низок - 0.2-0.3%, но всё же хотелось бы узнать, что это за зверь, насколько он нужен и как его отключить в случае ненужности?

Share this post


Link to post
Share on other sites

dazgluk

Дальнейшее увеличение hashsize не привело к каким-либо видимым изменениям. Однако, эта проверка была проведена уже на уменьшенной нагрузке, соответственно, завтра в ЧНН проведу еще один эксперимент

 

 

Так же, кажется, получил ответ на вопрос по поводу csw. Увеличение наблюдается на обеих машинках и связано, видимо, с жизнью других приложений на машинах. В частности, есть подозрение, что агент заббикса, используемый для мониторинга, "просыпается" как раз в моменты увеличения csw. Соответственно вопросы сняты.

 

Параллельно почитал другие топики и появились некоторые вопросы, косвенно связанные с увеличением производительности машинок. А именно:

1. Насколько в моём случае изменит ситуацию отключение intel_idle? Я не заметил его активной работы в моей системе, но в других топиках активно с ним борятся для получения максимальной производительности.

2. Что есть kipmi0 ? Этот процесс постоянно вылазит в dstat --top-cpu. Его вклад крайне низок - 0.2-0.3%, но всё же хотелось бы узнать, что это за зверь, насколько он нужен и как его отключить в случае ненужности?

 

Кстати хотел сказать что у нас жестко задана частота CPU через CPUFREQ, если этого не сделать, были дропы пакетов в момент изменения частоты процессора.

Share this post


Link to post
Share on other sites

итак, conntrack_count уже более 800 тыс, трафика тоже больше 6Гбит. Установка hashsize 393216, 524288 не дает видимого эффекта в изменении нагрузки на процессор. То есть фактически никаких изменений ни в лучшую, ни в худшую сторону. Однако по perf top -e cache-misses видно, что nf_nat_setup_info в процентном соотношении больше приносит событий cash-miss. То есть вымывание из кэша действительно присутствует при увеличенном hashsize, но влияние этого дела на общий процесс незначительно.

Так же заметил, что больше всего cache-miss у меня в процессе ip_route_input, хотя таблица маршрутизации - 9 строк, ipv6 нет. А вот как получить суммарную информацию по этим событиям для ядра - я не понял. perf stat требует команду для выполнения, а мне надо на систему смотреть. может кто-нить подсказать?

 

По поводу фиксированной частоты процессора - я не видел, чтобы она у меня изменялась. А вот счетчики ухода ядер в S1-S3 увеличиваются. Видимо всё-таки надо будет вынести intel_idle при перезагрузке. Ну и хотелось бы уточнить - имеет ли смысл фиксировать ITR, или и так драйвер при большой нагрузке адекватное значение выставляет в 35-36 тыс прерываний? Ночью при очень низком трафике значения увеличиваются на одной машине скачкообразно до 70k, а затем плавно до 75k-80k, на другой - плавно до 75k. При малом трафике это не напрягает, при большом - вроде всё ок.

Share this post


Link to post
Share on other sites

junjunk2 Спасибо за тест с hashsize

Посмотрел что у вас еще старое ядро. У нас

Linux nat-10g-5 3.12-0.bpo.1-amd64 #1 SMP Debian 3.12.9-1~bpo70+1 (2014-02-07) x86_64 GNU/Linux

Если планируете использовать ipt_netflow, последняя версия с lockless листами вроде требует минимум 3.6

 

Касаемо ITR, у нас он начинал чудить на среднем трафике, то есть ~ c 11.00 по 16.00, вылезали rx_missed_errors, при ~ 30-40% CPU. В ЧНН все становилось нормально, но решили его таки фиксировать чтобы избежать дропов.

Share this post


Link to post
Share on other sites

dazgluk

по поводу ядра - это CentOS 6, там в принципе много backports сделано, так что пока не планирую переходить куда-то выше. Хотя на этом форуме была вроде как информация о том, что ядро 3.17.3 сильно лучше по сетевой производительности, причем из репозитория elrepo. Было бы где потестить - можно было бы рискнуть, а на боевые машинки при таком трафике - не хотелось бы бороться с неизведанными глючками под истошные вопли абонентов.

 

а по поводу ошибок, у меня вот так:

nat:
NIC statistics:
    rx_packets: 12135277669610
    tx_packets: 11915395376792
    rx_bytes: 9712454469371002
    tx_bytes: 9691248040910242
    rx_errors: 518511824
    tx_errors: 0
    rx_dropped: 0
    tx_dropped: 0
    multicast: 10865837
    collisions: 0
    rx_over_errors: 0
    rx_crc_errors: 518190473
    rx_frame_errors: 0
    rx_fifo_errors: 0
    rx_missed_errors: 0
    tx_aborted_errors: 0
    tx_carrier_errors: 0
    tx_fifo_errors: 0
    tx_heartbeat_errors: 0
    rx_pkts_nic: 12136513252031
    tx_pkts_nic: 11915395376940
    rx_bytes_nic: 9798625412121271
    tx_bytes_nic: 9787556616335292
    lsc_int: 102
    tx_busy: 0
    non_eop_descs: 0
    broadcast: 16012388
    rx_no_buffer_count: 0
    tx_timeout_count: 1
    tx_restart_queue: 203015
    rx_long_length_errors: 0
    rx_short_length_errors: 0
    tx_flow_control_xon: 0
    rx_flow_control_xon: 0
    tx_flow_control_xoff: 0
    rx_flow_control_xoff: 0
    rx_csum_offload_errors: 18334641
    alloc_rx_page_failed: 0
    alloc_rx_buff_failed: 0
    lro_aggregated: 0
    lro_flushed: 0
    rx_no_dma_resources: 1235582267
nat2
NIC statistics:
    rx_packets: 15430823833170
    tx_packets: 15125975000868
    rx_bytes: 12303754816831551
    tx_bytes: 12277927317976374
    rx_errors: 185
    tx_errors: 0
    rx_dropped: 0
    tx_dropped: 0
    multicast: 11423208
    collisions: 0
    rx_over_errors: 0
    rx_crc_errors: 185
    rx_frame_errors: 0
    rx_fifo_errors: 0
    rx_missed_errors: 0
    tx_aborted_errors: 0
    tx_carrier_errors: 0
    tx_fifo_errors: 0
    tx_heartbeat_errors: 0
    rx_pkts_nic: 15431793993733
    tx_pkts_nic: 15125974174732
    rx_bytes_nic: 12417753438060887
    tx_bytes_nic: 12404078003015900
    lsc_int: 99
    tx_busy: 0
    non_eop_descs: 0
    broadcast: 15532370
    rx_no_buffer_count: 0
    tx_timeout_count: 3
    tx_restart_queue: 5296419
    rx_long_length_errors: 0
    rx_short_length_errors: 0
    tx_flow_control_xon: 175
    rx_flow_control_xon: 0
    tx_flow_control_xoff: 2444
    rx_flow_control_xoff: 0
    rx_csum_offload_errors: 29241321
    alloc_rx_page_failed: 0
    alloc_rx_buff_failed: 0
    lro_aggregated: 0
    lro_flushed: 0
    rx_no_dma_resources: 970883167

на машине nat после ребута неправильно отработал скрипт прибивания к ядрам, поэтому вылезли ошибки в большом количестве. но они не растут.

меня печалят rx_no_dma_resources и tx_restart_queue. как с ними бороться нигде не могу найти. может что-нить посоветуете?

 

PS. сегодня перешагнул порог 1.3Mpps при 8.6Гбит/с и загрузке в 70%. conntracks >1млн. увеличение conntrack_buckets не дает никакого ощутимого прироста

Edited by junjunk2

Share this post


Link to post
Share on other sites

rx_no_dma у нас начали появляться, когда мы раздули RING до 4096, уменьшение обратно на 2048 помогло. Как я понял, этот счетчик увеличается когда сетевка не успевает выгрузить пакеты в оперативку. Нарисуйте график snmp i/o drops, нужно понять, в ЧНН они начинают расти или нет.

Что касается tx_restart_queue, ни раз не сталкивались

Share this post


Link to post
Share on other sites

Как я понял, этот счетчик увеличается когда сетевка не успевает выгрузить пакеты в оперативку.

Скорее - когда нет непрерывного куска достаточного объема dma памяти для выгрузки пакетов.

Share this post


Link to post
Share on other sites

1.

Однако по perf top -e cache-misses видно, что nf_nat_setup_info в процентном соотношении больше приносит событий cash-miss. То есть вымывание из кэша действительно присутствует при увеличенном hashsize

 

Не обязательно. "perf top -e cache-misses" вам показывает проценты, а процентов всегда в сумме 100. Дальше, perf вам показывает, что какие-то функции из этих 100% отъели больше чем другие. Ну и что?

 

Предлагаю измерять так:

 

# perf stat -a -e cache-misses,cache-references sleep 10

Performance counter stats for 'system wide':

        2,215,694      cache-misses              #    0.918 % of all cache refs     [100.00%]
      241,380,692      cache-references

     10.000867228 seconds time elapsed

 

И тут смотрим на "cache-misses ...% of all cache refs". Проводим три теста:

 

1. hashsize=nf_conntrack_count - это будет исходным значением (benchmark), остальные два сравниваем с ним:

2. hashsize=nf_conntrack_count/2

3. hashsize=nf_conntrack_count*2

 

(Ну или вместо 2, сделать 8. Вместо conntrack_count conntrack_max.) Проводим тест несколько раз, чтоб убедиться что цифры стабильные.

 

Если "cache-misses % of all cache refs" растёт, значит кэш используется менее эффективно, если уменьшается, то более эффективно.

 

2.

Насчет идеи, что уменьшение hashsize позволит хэшу коннтрака умещаться в кэше (а следовательно увеличивает скорость доступа), это на мой взгляд ошибочно. Хэш таблица целиком состоит из двух частей: маленький индекс (размер которого вы контролируете параметром hashsize или nf_conntrack_buckets), и связанные-списки структур данных о соединениях на которые и указывает индекс. К индексу доступ однократный, к спискам последовательный перебор. Доступ к индексу использует 1 cache-line, доступ к списку в среднем столько cache-lines сколько там элементов (деленное на два для усреднения).

 

Соответственно, если вы уменьшаете индекс в N раз, то вы увеличиваете списки в N раз, в результате делаете в среднем в N/2 раз больше обращений к памяти, следовательно, в N/2 раз больше используется кэш. Это не считая того, что в N/2 раз больше выполняется операций поиска нужного элемента.

 

3.

Насчет связи hashsize с conntrack_max. nf_conntrack_max это же просто ограничитель использования памяти, он не влияет непосредственно на текущую производительность, поэтому связь hashsize = conntrack_max/N ничего не значит в плане нагрузки или использования кэша, так как не дано текущее количество соединений. Формула hashsize = conntrack_max/8, значит что в среднем списки не будут расти больше 8, то есть защита от многократного роста нагрузки из-за длинных списков (скажем, во время DoS атаки).

 

 

А вот как получить суммарную информацию по этим событиям для ядра - я не понял. perf stat требует команду для выполнения, а мне надо на систему смотреть. может кто-нить подсказать?

 

Указывайте опцию -a (все процессоры) и команду sleep.

Edited by aabc

Share this post


Link to post
Share on other sites

Если планируете использовать ipt_netflow, последняя версия ... вроде требует минимум 3.6

 

Не требует.

 

меня печалят rx_no_dma_resources и tx_restart_queue. как с ними бороться нигде не могу найти. может что-нить посоветуете?

Вот к примеру разговор с интеловцем по сходной проблеме http://comments.gmane.org/gmane.linux.drivers.e1000.devel/11667

 

rx_no_dma_resources и rx_missed_errors - значит растёт очередь, а следовательно latency.

 

rx_no_dma у нас начали появляться, когда мы раздули RING до 4096, уменьшение обратно на 2048 помогло.

 

Видимо проблема buffer bloat. Возможно, лучше чтоб были дропы чем рост очереди и latency у всех клиентов. Дропы, если они не так часто, то нормальное явление для TCP, будет ретрансмит и всё.

 

Кстати, в ethtool -C же можно контролировать как часто делать прерывания (хоть после каждого пакета). Плюс, у некоторых драйверов интела есть умные адаптивные алгоритмы, которые можно включить (InterruptThrottleRate=). В последних ядрах так-же решали что-то с buffer bloat.

Edited by aabc

Share this post


Link to post
Share on other sites

Я тут думаю зайду после выходных почитаю тему, в ожидании увидеть очередное обсуждение количества ядер или размер буфера, а тут МЯСО по коннтраку. Спасибо junjunk2, интересный эксперимент. Спасибо что провели, оформили и поделились. Все бы так.

 

Поставьте 1.5М хэш, посмотрим что будет :) Куча cache misses и все плохо. Хотя коллизий не будет совсем :)

 

Выяснили, что /8 пока решает.

 

LARTC никоим образом не учитывает размер кеша проца. А по хорошему хеш должен сидеть в кеше для оптимального быстродействия (лучше - в л2 если будет жить, но как минимум - не вымываться из л3).

 

Тут я согласен aabc, который подробно всё расписал. Судя по всему соотношение /8 является оптимальным. Более того, не забываем, как производится поиск по хешу, там скорее всего B-tree ( или что-то умнее ), и как только символ не совпадает, мы переходим на следующую ветку дерева. В этом случае слишком короткий хеш будет давать очень длинные ветви по которым нужно долго спускаться, не смотря на то, что значение самих листьев не значительно и влазит в кеш.

 

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

 

Вопрос стоял именно в 2-кратном приросте производительности при 2-кратном увеличении кол-ва ядер. Потому как реально там будет совсем не в 2 раза рост. И от того вполне возможно, что 2 мелких тазика окажутся более предпочтительными, чем 1 монстр. И по цене, и по производительности, и по надежности (ибо резерв).

 

Я не говорил о двухкратном приросте, речь шла именно о 4х ядерной системе для трафика больше 10Гбит. Так же обращаю ваше внимание, что я тоже советую ТС разнести нагрузку на 2 железки.

 

Медленная подсистема памяти сливает все прелести ядер.

 

А есть какие-то тесты? Потому что на сколько я помню, АМД первые начали ставить контроллер памяти на кристал с процессором, что как раз нивелировало эту проблему.

 

О размере буфера и ITR. У меня бывали случаи, когда динамический ITR начинал творить треш. Типа 1К прерываний на ядро, при куче трафика и другие не понятные вещи. Бывало, что он работал нормально ( разные версии драйвера ). Динамический ITR умеет два режима: 70K при низком трафика ( почти realtime - пакет, прерывание ), или 40К ( при большой нагрузке ).

 

Когда начинаются чудеса с потерей пакетов, я всегда перевожу тазик на ручной ITR. Это требует немного внимания, конечно, зато позволяет всё правильно зарегулировать и избежать проблем. Например, можно сделать минимальный буфер, и побольше прерываний, таким образом уменьшая задержку обработки пакетов ( там где это критично ), и по мере роста нагрузки буфер увеличивать.

 

В общем случае, на максимально загруженой машине буфер максимален, а количество прерываний настроено так, чтобы при полной расчетной загрузке машины ( например DOS ), карта не теряла пакеты потому что кончился буфер. Но бывали ситуации, когда увеличение буфера до максимума устраивало перегрузку других подсистем и это было не еффективно.

 

Так же нужно быть аккуратным с выбором мамы. Потому что можно уперется в шину PCIe. Ошибки типа rx_no_dma - это оттуда. Карта не успевает отдать все пакеты из буфера за прерывание и теряет их. Надо чтобы было PCIe v3 хотябы с 128 GT/s ( это 8 GT/s per lane ) для 16х.

 

Если этого нет, то всё будет плохо. Можно, конечно сделать меньше буфер и чаще прерываться, но мы же все понимаем последствия этого решения.

 

Насчет ядра ТС - согласен. Не надо ничего менять. У меня есть тазики на 2.6.27. If it's working, don't fix it.

 

kipmi - это процесс IPMI. Не понятно только почему он ест процессорное время. Может кто-то ломится к вам на IPMI порт?

Edited by Dark_Angel

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now