Потери на сетевых картах, задержки в обработке и как с ними бороться

Ключ
Эта строка удалена.
Это слово было удалено. Это слово было добавлено.
Эта строка добавлена.

Изменения (89)

просмотр истории страницы
{toc}

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

На постоянное использование можно добавлять команды в хук start.sh в функцию client_post_start_hook().

Итак, вещи:
h1. Network Top

{toc}
В комплекте с редуктором поставляется утилита

{code}
chroot /app/reductor network-top
{code}

Разберём их по порядку:
Запускается без аргументов, показывает полную картину нагрузки на сетевые карты и ядра процессора в реальном времени. Аномально высокие значения подсвечиваются желтым (больше нормы) или красным (критично) цветом.


h1. Размер буфера сетевой карты

{code}

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

{code}
ethtool -G eth1 rx 4096
{code}
В Carbon Reductor DPI X при добавлении сетевой карты для фильтрации через мастер для неё автоматически настраивается оптимальный размер RX-буфера.

CentOS позволяет указывать параметры ethtool в качестве опции в настройках интерфейса (/etc/sysconfig/network-scripts/ifcfg-eth1), например строчкой
{code}
ETHTOOL_OPTS='-G eth1 rx 4096'
{code}
Также он настраивается автоматически при использовании опции FWBOOST.

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

h1. Распределение прерываний

Многие сетевые карты имеют несколько очередей для входящих пакетов. Каждая очередь висит на ядре/списке ядер. На многих железках из коробки, несмотря на то, что в smp_affinity_list указан список 0-$cpucount все прерывания находятся на первом ядре процессора. Обойти это можно раскидав с помощью echo все прерывания на разные ядра.
{include:reductor5:Распределение прерываний}

По возможности используйте разные реальные ядра, допустим, дано:

- 1 процессор с гипертредингом
- 4 реальных ядра
- 8 виртуальных ядер
- 4 очереди сетевой карты, которые составляют 95% работы сервера

Раскинуть их на 0, 1, 2 и 3 ядра будет не так эффективно, как на 0, 2, 4 и 6.

Пример кода (костыльный и неуниверсальный), который раскидывает 8 очередей на 8 ядер (довольно простой случай).
Строка "-TxRx" - по ней можно идентифицировать очереди сетевой карты принимающей зеркало трафика, может отличаться в зависимости от модели сетевой карты и драйвера, посмотреть как она выглядит можно в файле cat /proc/interrupts

{code}
#!/bin/bash

tune_nic() {
echo "- Настраиваем прерывания $1"
local nic="$1$2"
local cpucount=$(grep -c 'model name' /proc/cpuinfo)
grep $nic /proc/interrupts | while read irq $(eval echo cpu{1..$cpucount}) _ queue _; do
irq=${irq//:}
proc_entry=/proc/irq/$irq/smp_affinity_list
evaled="${queue##*rx-}"
echo $evaled > $proc_entry
done
}

client_post_start_hook() {
tune_nic "eth1" "-rx"
tune_nic "eth2" "-TxRx"
}
{code}

h1. Мощность ядер процессора

{code}
[root@centos ~]# grep '' /sys/devices/system/cpu/cpu0/cpufreq/scaling_{min,cur,max}_freq
/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq:1600000
/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq:1600000
/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq:3201000
{code}
В Carbon Reductor DPI X процессор автоматически настраивается на максимально доступную базовую частоту.

Суть видна - довольно мощный процессор работает в полсилы и даже не собирается напрягаться.

Заставить их напрячься можно так:

{code}
#!/bin/bash
h1. Настройки rx-usecs

cpucount=$(grep -c 'model name' /proc/cpuinfo)
sysdir=/sys/devices/system/cpu
for cpu in $(eval echo cpu{0..$((cpucount-1))}); do
cat $sysdir/$cpu/cpufreq/scaling_max_freq > $sysdir/$cpu/cpufreq/scaling_min_freq
done
{code}
В Carbon Reductor DPI X автоматически подбирается оптимальное значение этого параметра для сетевой карты при использовании опций FWBOOST.

h1. Различные значения rx-usecs

Не буду плодить энтропию, так что вот ссылка на хорошую статью (правда заточенную под маршрутизаторы больше): [http://habrahabr.ru/post/108240/]


h1. Замена сетевых карт

Иногда бывает дело в используемом оборудовании. Если Вы уверены, что сетевая карта хорошей модели и есть ещё одна такая же - попробуйте использовать её. Возможно она просто бракованная.

Иногда дело бывает в драйвере (в случае dlink / realtek сетевых карт). Они не подходят для высоких нагрузок.

h1. Отключение гипертрединга

В некоторых случаях использование процессора с отключенным гипертредингом оказывалось эффективнее, чем с включенным, несмотря на меньшее количество логических ядер.

Делать это стоит, если все предыдущие пункты не помогают.


h1. Включение RPS

В Carbon Reductor DPI X эта технология автоматически настраивается для сетевых карт с одной очередью.

В кратце - можно за счёт повышения нагрузки на процессор слегка снять нагрузку с сетёвки уменьшая rx-usecs. На большинстве машин использумых в нашем случае оптимальным оказалось значение 1.
При использовании опции FWBOOST эта технология автоматически настраивается в сочетании с RSS.

{code}
ethtool -C eth1 rx-usecs 1
{code}

h1. Замена сетевых карт

Иногда бывает дело просто в железе. Если уверены, что сетевая карта хорошей модели и есть ещё одна такая же - попробуйте использовать её. Возможно она просто бракованная, хоть вероятность и мала.
h1. Актуализация настроек зеркала трафика

Иногда дело бывает в драйвере (в случае dlink / realtek сетевых карт). Они, конечно, здорово поддерживаются практически любым дистрибутивом, но для высоких нагрузок не очень подходят.
Разнесение всех интерфейсов зеркала трафика по отдельным бриджам даёт снижение нагрузки.

h1. Отключение гипертрединга
h1. Использование нескольких сетевых карт для приёма зеркала

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

Делать это стоит, если все предыдущие пункты не помогают.

h1. NOTRACK (экспериментально)
h1. MTU

Если вы уверенны в отсутствии петель в зеркале (в Carbon Reductor не попадает его собственный трафик, можно проверить это с помощью tcpdump), то можно поэкспериментировать с этой опцией. Если в течение пары-тройки часов после включения проблем с выгрузкой и работой сети на Carbon Reductor не возникло, то её можно использовать. Она применяет ко всем пакетам идущим на интерфейсы во всех бриджах правило с \-j NOTRACK, что приводит к значительному снижению нагрузки на процессор.
MTU на порту коммутатора, отправляющего зеркало не должно быть больше, чем MTU интерфейса на Carbon Reductor (в том числе и всех VLAN), принимающего зеркалированный трафик.

Рекомендуем посмотреть статистику на коммутаторе по распределению размеров пакетов, для D-Link например команда

Можно с tcpdump на интерфейсах в бридже послушать:
{code}
tcpdump -nneei <сетёвка в зеркале> -с 100 host <ip с которого редуктор в инет ходит и редиректы шлёт>
show packet port 1:1
{code}

в другом окне ssh при этом
и вывод в духе:

{code}
curl ya.ru
nslookup google.com
Port number : 2:11
Frame Size/Type Frame Counts Frames/sec
--------------- ---------------------- -----------
64 1470536789 6330
65-127 511753536 12442
128-255 1145529306 1433
256-511 704083758 1097
512-1023 842811566 882
1024-1518 1348869310 7004
1519-1522 2321195608 1572
1519-2047 2321195608 1572
2048-4095 0 0
4096-9216 0 0
Unicast RX 0 0
Multicast RX 16 0
Broadcast RX 0 0
Frame Type Total Total/sec
--------------- ---------------------- -----------
RX Bytes 1384 0
RX Frames 16 0
TX Bytes 20409818277370 15162751
TX Frames 34114583632 30760
{code}
если ни в одном из интерфейсов куда зеркало валится таких пакетов нет, то можно включать NOTRACK.

По дефолту, CentOS ставит MTU = 1500, лучше выставить его равным максимальному ненулевому значению из статистики.

Крупным провайдерам с большим объёмом трафика эта опция практически обязательна, почему - показывает пример:

ДО включения:
{code}
88.4%si
82.3%si
88.2%si
75.9%si
100.0%si
82.9%si
88.5%si
84.7%si
90.3%si
94.6%si
82.0%si
67.9%si
77.5%si
100.0%si
82.9%si
100.0%si
82.0%si
100.0%si
85.0%si
93.8%si
90.3%si
91.2%si
89.3%si
100.0%si
87.3%si
97.3%si
91.1%si
94.6%si
100.0%si
87.6%si
81.7%si
85.7%si
1519-2047 2321195608 1572
{code}

ПОСЛЕ включения:
h2. Как определить потери пакетов из-за низкого MTU?

Посмотрите на RX: length значение.

{code}
1.2%si
2.4%si
0.0%si
0.0%si
0.0%si
0.0%si
0.0%si
0.0%si
0.0%si
1.3%si
1.2%si
0.0%si
1.2%si
0.0%si
0.0%si
0.0%si
0.0%si
0.0%si
0.0%si
0.0%si
1.4%si
0.0%si
1.3%si
0.0%si
0.0%si
0.0%si
0.0%si
0.0%si
0.0%si
1.4%si
1.5%si
0.0%si
# ip -s -s link show eth1
3: eth1: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1528 qdisc mq state UP qlen 1000
link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped overrun mcast
5956390755888 19345313821 3533855 0 0 817154
RX errors: length crc frame fifo missed
3533855 0 0 0 0
TX: bytes packets errors dropped carrier collsns
23100 330 0 0 0 0
TX errors: aborted fifo window heartbeat
0 0 0 0
{code}

h1. Включение RPS (актуально для realtek/dlink/бюджетных intel)
Как избавиться от этих потерь?

Примечание - включать надо для всех vlan на сетевой карте отдельно. Включение только для самого девайса ethX не снизит нагрузку, создаваемую обработкой пакетов с vlan-интерфейсов.

Разово:

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

Пока можно включить руками или добавив в хук команду в духе:

{code}
cpucount="$(grep -c 'model name' /proc/cpuinfo)"
printf "%x\n" $((2**cpucount-1)) > /sys/class/net/eth1/queues/rx-0/rps_cpus
ip link set eth1 mtu 1540
{code}

h1. Актуализация настроек зеркала трафика
На постоянной основе:

Разнесение всех интерфейсов зеркала трафика по отдельным бриджам даёт небольшое снижение нагрузки за счёт устранения небольшой петли.
Дописать в конфиг сетевой карты (например /etc/sysconfig/network-scripts/ifcfg-eth1):

h1. Использование нескольких сетевых карт для приёма зеркала
{code}
Вы можете раскидать зеркало между несколькими сетевыми картами, указав в настройках создаваемых зеркал равные диапазоны абонентских портов.
MTU=1540
h1. Отключение логирования
{code}
menu > настройки алгоритма фильтрации > логировать срабатывания

отключите эту опцию, это _немного_ ускорит процесс обработки пакета и отправки редиректа. Однако несмотря на "немного", при очень частых срабатываниях - способно даже немного снизить нагрузку на процессор.