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

Поддержка многопоточной обработки на Intel PRO/1000 MT в FreeBSD 8 Распараллеливание при большом pps

Имеется веб-сервер на FreeBSD 8.1 с сетевой Intel PRO/1000 MT PCI-X.

В данный момент идет входящий поток до 250 kpps (synflood).

Исходящий (syn cookie) - до 150 kpps.

 

Как ни изгаляюсь с net.isr.direct, net.isr.maxthreads и другими параметрами, не получается входящий поток пакетов раскидать на несколько ядер.

Всегда обработка ведется одним ядром, которое загружается на 100%,

и начинаются проблемы с доступом к сайту.

 

Polling в ядре отключен.

 

Ошибок на вход в netstat -w 1 нет.

 

 

Пробовал ставить дрова от яндекса, но они при загрузке получаю:

Intel® PRO/1000 Legacy Network Connection 1.0.1

и фичи от яндекса недоступны.

 

Подобной проблемы не было на другом сервере со встроенной PCI-Express сетевой.

 

Остальных настроек не касаюсь,так как они проверены опытом и 100% рабочие.

 

Интересует только возможность распараллеливания входящего потока между несколькими ядрами на сетевой карте Intel PRO/1000 MT / PWLA8490MT.

Менять на PCI-Express карту - долго, так как сервер находится в ДЦ за бугром.

 

У кого какой опыт в данном вопросе?

 

Спасибо.

Share this post


Link to post
Share on other sites

В идеале хотелось бы запустить полноценно дрова от яндкеса, без использования ner.isr.direct.

Так как они себя зарекомендовали при син-флуд атаке на другом сервере при блее высоких нагрузках.

 

 

Share this post


Link to post
Share on other sites
Интересует только возможность распараллеливания входящего потока между несколькими ядрами на сетевой карте Intel PRO/1000 MT / PWLA8490MT.

Менять на PCI-Express карту - долго, так как сервер находится в ДЦ за бугром.

Или ставьте igb, или пилите netisr.c (и еще пару файлов где сидит код приема пакета с драйвера) для раскидывания трафика. Там просто... :) Но установка igb - правильное решение.
Edited by bitbucket

Share this post


Link to post
Share on other sites
Или ставьте igb, или пилите netisr.c (и еще пару файлов где сидит код приема пакета с драйвера) для раскидывания трафика
Пара файлов легко превращается в пару десятков взаимосвязанных файлов, netisr среди них далеко не самый главный и большой.

А скорости можно выжать даже если пооптимизировать if_ethersubr.c, а ещё есть if.c где вообще всё кодом поросло :)

Share this post


Link to post
Share on other sites
Пара файлов легко превращается в пару десятков взаимосвязанных файлов, netisr среди них далеко не самый главный и большой.
Если конкретно - 3 файла: netisr.c, if_vlan.c, if_ethersubr.c. Хотя igb решает вопрос более правильно.

 

Share this post


Link to post
Share on other sites
Имеется веб-сервер на FreeBSD 8.1 с сетевой Intel PRO/1000 MT PCI-X.

В данный момент идет входящий поток до 250 kpps (synflood).

Когда идет synflood, надо сначала бороться с synflood (настроить ipfw и банить IP-адреса, с которых он идет), и только потом уже думать о проблеме устранения гигантских блокировок в ядре. Кстати, а что за веб-сервер используется? И почему вы считаете, что нагрузка на процессор создается именно на уровне ядра, а не в юзерлэнде от установки соединения с сервером? Это будет очевидно, если вы приведете вывод top. По поводу устранения локов: если у igb проблем с масштабированием на SMP нет, значит проблему надо устранять в драйвере em, а не в коде, который используется для любых сетевух. Я не думаю, что обычный админ, не являющийся коммитером FreeBSD, потянет такую задачу, как устранение гигантских блокировок, поэтому, как я уже говорил, проще написать скрипт, который будет периодически запускаться, измерять пакетрейт и банить флудеров по IP.
Edited by photon

Share this post


Link to post
Share on other sites

Если конкретно - 3 файла: netisr.c, if_vlan.c, if_ethersubr.c

ether_input -> ether_demux -> ip_fastforward

Share this post


Link to post
Share on other sites
ip_fastforward
А вот его как раз и раскидывать на несколько процессоров.

 

Но synflood желательно еще до роутинга отчистить...

 

Share this post


Link to post
Share on other sites

У топикстартера вообще-то веб-сервер, а не роутер.

Share this post


Link to post
Share on other sites
А вот его как раз и раскидывать на несколько процессоров.
Нечего там раскидывать.

Замысел в том, что то что можно не обрабатывать идёт почти напрямую на выход, с минимум проверок и обработок. Там вроде даже блокировок нигде нет, если ресурсы типа адресов на интерфейсе и таблицы роутинга не заняты на запись.

ip_fastforward меньше чем ip_input и ip_output даже по отдельности.

 

 

У топикстартера вообще-то веб-сервер, а не роутер.
А это не важно, ether_input -> ether_demux -> ip_fastforward всё равно так и идёт для всех принятых с эзернета пакетов.

Просто ip_fastforward в куче случаев возвращает пакет обратно, в том числе и когда пакет для этого хоста, а уже после не состоявшейся обработки в ip_fastforward оно идёт на netisr.

 

Share this post


Link to post
Share on other sites
Нечего там раскидывать.
Почему ? Идея как раз раскидать обработку пакетов (роутинг+фаервол) между многими головами. em это делать не умеет. Соответственно это можно сделать софтовым способом: первый - использовать фрайвер от yandex-а, второй - раскидывать пакеты на кучу netisr.

 

ЗЫ: кстати, сей трюк с раскидыванием трафика на кучу netisr весьма процессорозависимый. Т.е. надо смотреть как оно в конкретном месте работать будет.

Edited by bitbucket

Share this post


Link to post
Share on other sites
Почему ? Идея как раз раскидать обработку пакетов (роутинг+фаервол) между многими головами. em это делать не умеет. Соответственно это можно сделать софтовым способом: первый - использовать фрайвер от yandex-а, второй - раскидывать пакеты на кучу netisr.
Потому что в случае фастфорвада на раскидывание его куда то уйдёт больше ресурсов, чем на обработку.

 

А вот как раз когда фаст форвард не срабатывает оно и уходит в netisr.

Или да, сам драйвер должен вызывать ether_input с разных потоков, те сам параллелить.

Но это не системный подход: придётся переписывать другие драйвера для добавления этой фичи.

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

 

 

PS: посмотрев на драйвер em, его размер - может показаться что вся сила интеловых сетевух не в железе :)

Share this post


Link to post
Share on other sites
Потому что в случае фастфорвада на раскидывание его куда то уйдёт больше ресурсов, чем на обработку.
Выбрать очередь netisr по алгоритму round-robin (плюс еще кое-какие мелкие проверки) и поставить в нее пакет не сильно будет ресурсы есть. А дальше задача netisr прожевать пакет: роутинг там, фаервол и т.д.

 

Share this post


Link to post
Share on other sites

Реализуйте, тестируйте, и сливайте в общее пользование :)

 

У меня уже нет слов чтобы писать что фастфорвард сам по себе в распараллеливании не нуждается, и что он и есть короткая-оптимизированная альтернатива цепочке: netisr -> ip_input -> ip_output

netisr я не копал, но там вроде очереди, как я понял, а фастфорвард работает без очереди, прогоняя пакет насквозь за раз.

 

А если при пересборке ядра не объявлять

ALTQ

IPFIREWALL_FORWARD

то можно получить дополнительно небольшое снижение нагрузки на проц на роутинге.

Share this post


Link to post
Share on other sites
Реализуйте, тестируйте, и сливайте в общее пользование :)
Копаем, пока вроде удачно :)

 

У меня уже нет слов чтобы писать что фастфорвард сам по себе в распараллеливании не нуждается, и что он и есть короткая-оптимизированная альтернатива цепочке: netisr -> ip_input -> ip_output

netisr я не копал, но там вроде очереди, как я понял, а фастфорвард работает без очереди, прогоняя пакет насквозь за раз.

Вы, видимо, плохо копали и не совсем понимаете как оно работет.

Задача по роутингу и фильтрации довольно тяжелая в случае высокого pps, igb данную задачу решает раскидывая обработчик пакетов на несколько голов процессора. Но, это не всегда оптимально: там по хешу работает, из-за чего часть ядер будет 100%, а часть будет курить, в зависимости от трафика. Чаще, конечно, оно ровненько раскидывается. А вот в случае em может быть один обраборчик. Так вот, когда net.isr.direct(_force)?=1 и fastforwarding то задача по роутингу и фильтрации выполняется в контексте обработчика прерывания. Но можно сделать, когда пакет в обработчике прерывания будет только ставится в очереь какой-то netisr, а оно уже будет его роутить и фильтровать. В случае правильного раскидывания получится софтовый вариант igb или некое подобие драйвера от yandex. Т.е. основная задача переедет из прерывания карточки в отдельный процесс, который легко раскидать на несколько ядер.

 

А если при пересборке ядра не объявлять

ALTQ

IPFIREWALL_FORWARD

то можно получить дополнительно небольшое снижение нагрузки на проц на роутинге.

А если вместо рутера патчкорд воткнуть вообще быстро будет. Медь решает. :)
Edited by bitbucket

Share this post


Link to post
Share on other sites
Имеется веб-сервер на FreeBSD 8.1 с сетевой Intel PRO/1000 MT PCI-X.

В данный момент идет входящий поток до 250 kpps (synflood).

Когда идет synflood, надо сначала бороться с synflood (настроить ipfw и банить IP-адреса, с которых он идет), и только потом уже думать о проблеме устранения гигантских блокировок в ядре. Кстати, а что за веб-сервер используется? И почему вы считаете, что нагрузка на процессор создается именно на уровне ядра, а не в юзерлэнде от установки соединения с сервером? Это будет очевидно, если вы приведете вывод top. По поводу устранения локов: если у igb проблем с масштабированием на SMP нет, значит проблему надо устранять в драйвере em, а не в коде, который используется для любых сетевух. Я не думаю, что обычный админ, не являющийся коммитером FreeBSD, потянет такую задачу, как устранение гигантских блокировок, поэтому, как я уже говорил, проще написать скрипт, который будет периодически запускаться, измерять пакетрейт и банить флудеров по IP.

Сотни тысяч адресов, которые не превышают допустимых лимитов по кол-ву подключений, которые постоянно меняются, и которые, судя по абузам от датацентров, еще и спуфятся.

Банить в этом случае - терять клиентуру сайта, который является крупным магазином.

Так можно и весь интернет забанить.

 

Бан работает в случае http-флуда, где спуфинг невозможен.

Да и то, с ограничениями.

 

Нагрузка идет в контексте прерывания.

До юзерленда она даже не доходит, так как коннекты не проходят проверку на син-куки.

В качестве веб-сервера - nginx.

 

Единственное решение в данном случае: сетевые PCI Express (даже левые рилтеки неплохо тянут) и хороший проц.

Таким образом держали атаку до 800 мбит с ппсом в 650к. Еще и запас по мощности оставался.

Даже ДЦ не выдержал и отключил.

 

Еще помогает dns load balancing.

 

 

Спасибо за советы.

Атаку выдержали за счет распределения dns.

 

Share this post


Link to post
Share on other sites
Вы, видимо, плохо копали и не совсем понимаете как оно работет.

Задача по роутингу и фильтрации довольно тяжелая в случае высокого pps, igb данную задачу решает раскидывая обработчик пакетов на несколько голов процессора. Но, это не всегда оптимально: там по хешу работает, из-за чего часть ядер будет 100%, а часть будет курить, в зависимости от трафика. Чаще, конечно, оно ровненько раскидывается. А вот в случае em может быть один обраборчик. Так вот, когда net.isr.direct(_force)?=1 и fastforwarding то задача по роутингу и фильтрации выполняется в контексте обработчика прерывания. Но можно сделать, когда пакет в обработчике прерывания будет только ставится в очереь какой-то netisr, а оно уже будет его роутить и фильтровать. В случае правильного раскидывания получится софтовый вариант igb или некое подобие драйвера от yandex. Т.е. основная задача переедет из прерывания карточки в отдельный процесс, который легко раскидать на несколько ядер.

У меня чуть чуть другие интересы в этом плане :)

Меня интересует процессинг пакетов с целью реализации в ng ноде ether <-> inet

Потому на netisr я не смотрю, как и на многое, ибо имею возможность выкинуть всё что не нравится.

 

Если не нравится как по хэшу работает - ищите хэш функцию получше.

 

Передача между ядрами или даже процами (пусть даже они в одном корпусе) процедура затратная

Share this post


Link to post
Share on other sites
У меня чуть чуть другие интересы в этом плане :)

Меня интересует процессинг пакетов с целью реализации в ng ноде ether <-> inet

А что, netgraph не раскидывает нагрузку по ядрам сам ? Для ng_pptp начиная с 7.2 оно очень весело расползается по всем ядрам,

даже в случае с em.

Share this post


Link to post
Share on other sites

alexon-ch, от вас так никто и не увидел ни top -ASHP, ни sysctl -a | grep isr

Share this post


Link to post
Share on other sites
alexon-ch, от вас так никто и не увидел ни top -ASHP, ни sysctl -a | grep isr

В этом нет необходимости уже.

И к тому же атаки уже нет, данные брать неоткуда.

 

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

Данная фича работает только с igb в 8-ке.

Дрова яндекса также работают только с карточками PCI Express.

 

Никакие другие извращения в случае с PCI-X (кроме переписывания кода) не помогут.

 

Поправьте меня, если неправ.

 

 

Share this post


Link to post
Share on other sites
Никакие другие извращения в случае с PCI-X (кроме переписывания кода) не помогут.

 

Поправьте меня, если неправ.

Есть патч, который делает кучу netisr в 7.х (как это сделано в 8.х). А раз есть куча netisr - можно и нагрузку между ними раскидать.

В 8.х это делается довольно легко, и дает прирост на 90% в производительности, раскидывая нагрузку по ядрам. Только ядер должно быть

действительно много (не 2, лучше 8).

Share this post


Link to post
Share on other sites
Никакие другие извращения в случае с PCI-X (кроме переписывания кода) не помогут.

 

Поправьте меня, если неправ.

Есть патч, который делает кучу netisr в 7.х (как это сделано в 8.х). А раз есть куча netisr - можно и нагрузку между ними раскидать.

В 8.х это делается довольно легко, и дает прирост на 90% в производительности, раскидывая нагрузку по ядрам. Только ядер должно быть

действительно много (не 2, лучше 8).

 

У меня 8-ка и 4 ядра.

Как раскидать нагрузку без изменения кода?

Никакие манипуляции с netisr не помогли.

 

На карте PCI Express все чудесно.

 

Share this post


Link to post
Share on other sites
Как раскидать нагрузку без изменения кода?
Купить железку которая будет раскидывать и ещё тазики.

 

 

А что, netgraph не раскидывает нагрузку по ядрам сам ? Для ng_pptp начиная с 7.2 оно очень весело расползается по всем ядрам,

даже в случае с em.

Меня интересует именно ethernet <-> inet, раскидывание нагрузки пока нет, ибо её нет.

Обычно пакеты будут проходить "насквозь", хотя reassemble и фрагментация для IP будут, в случае различия mtu на ethernet и inet хуков, для больших пакетов.

Никакого фаерволинга, bpf, if_bridge, if_carp и прочих не будет.

Share this post


Link to post
Share on other sites
Купить железку которая будет раскидывать и ещё тазики.

Это все понятно.

Вопрос уже таким образом решился.

 

Остался чисто академический интерес - можно ли это сделать на одном тазике с PCI-X.

 

Edited by alexon-ch

Share this post


Link to post
Share on other sites
У меня 8-ка и 4 ядра.

Как раскидать нагрузку без изменения кода?

Никак. Раскидыватель надо дописывать.

 

Причем, в вашем случае, когда надо чистить трафик от synflood - точно придется дописывать свой код в if_em.c .

 

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
Sign in to follow this