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

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

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

просмотр истории страницы
{toc}
Большинство настроек производительности сервера Carbon Reductor настраивает автоматически, но некоторые нужно подстраивать под конкретный сервер вручную. Если Ваш сервер перестал справляться с нагрузкой или вы хотите повысить запас производительности сервера, воспользуйтесь советами из этой статьи.

В Linux сетевое оборудование (процессор, сетевые карты) по умолчанию работает неидеально. Наша задача - поймать пакеты, не упустив ни одного и обработать, при этом желательно в реальном времени.
h1. Как оценить производительность сервера

h1. Как увидеть информацию о потерях
Для оценки будем использовать набор утилит в Carbon Reductor и стандартные инструменты iproute.

Для начала убедимся в существовании проблемы. Для этого будем использовать набор утилит в Carbon Reductor и стандартные инструменты iproute.

Все команды надо запускать перейдя в контейнер Carbon Reductor:

{code}

Обращать внимание нужно не только на наличие ошибок, но и на скорость их появления: например, они могут появиться разово во время настройки сетевой карты.


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

Если нагрузка распределена неравномерно, т.е. Cpu0 трудится, а 1..n нет, то ресурсы процессора используются нерационально.

* 0% на каждом ядре - возможно на сервере нет трафика.
* 1-3% - увеличение канала возможно без апгрейда оборудования.
* 6-10% - текущая нагрузка обрабатывается нормально, увеличение канала потребует апгрейд  оборудования.
* 11-15% - вероятно требуется апгрейд оборудования или оптимизации настроек имеющегося.
* 20-100% - с вероятностью 99% присутствуют потери пакетов. Если ситуация сохраняется после применения последующих пунктов этой статьи - свяжитесь с технической поддержкой.
Показатель "%si" растет нелинейно при повышении нагрузки. Чем больше в Вашем сервере ядер - тем больше они влияют друг на друга и тем сильнее растет "%si".


Если значение стабильно выше 60-80% - что сервер работает практически на пределе. Если подходит к 100% - сервер начинает плохо справляться с фильтрацией (пакеты начинают теряться или обрабатываются с задержкой).



h2. Информация о сетевом стеке

{code}

Данные собираются из нескольких источников (`/proc/interrupts`, `/proc/softirqs`, `/proc/net/softnet_stat` и др) и представленны в удобочитаемом виде. По умолчанию отображаются изменения по сравнению с предыдущими значениями. Режим `--no-delta-mode`, отображает абсолютные значения.

h3. /proc/interrupts

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

Если в одну очередь приходит больше пакетов, чем в остальные - возможно трафик инкапсулирован (QinQ, PPP).

Если в одну очередь приходит больше пакетов, чем в остальные - возможно трафик инкапсулирован (QinQ, PPP), что мешает сетевой карте равномерно их распределить.

h3. Load per CPU

Отображает что делает каждое ядро. Распределение обработки трафика может достигается за счёт очередей сетевой карты (RSS) или технологии RPS ("программный" RSS).

* Interrupts - прерывания, это копирование пакетов из сетевой карты в оперативной памяти.
* Interrupts - прерывания от сетевой карты
* NET_RX - отложенная обработка входящего трафика: собственно обработка пакетов файрволом
* Total - число обрабатываемых пакетов
* dropped - потери пакетов
* time_squeeze - задержки пакетов - пакет не успел обработаться за отведённое время, отложен для обработки позже. Наличие задержек - признак того, что сервер перестаёт справляться с нагрузкой.
* time_squeeze - количество дополнительных циклов обработки пакетов из 1 прерывания. При наличии потерь, косвенно указывает что именно ядро не справляется с обработкой пакетов (при большом количестве циклов, более 100-300)

h3. Network devices
Частые проблемы в настройках процессора.

h3. "Плавающая" частота

{code}
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}

Проблема - процессор работает вполсилы. Исправить это можно используя утилиту `maximize-cpu-freq` входящую в netutils-linux, в Carbon Reductor 8 она используется автоматически.

h3. Режим энергосбережения

Ещё одно "но", которое приводит к проблемам и которое сложно выяснить программным путём - режим энергосбережения в UEFI или BIOS, который у некоторых процессоров Intel Xeon приводил напротив, к повышению нагрузки. Лучше выключить эту опцию, выбрав режим "производительность" (для этого потребуется перезагрузить сервер).
У многих процессоров существует режим энергосбережения в UEFI или BIOS. Это трудно определить программным путем, поэтому лучше сразу, при настройке сервера, выключить эту опцию, выбрав режим "производительность".


h3. DCA

h3. Низкая частота

Процессоры с большим числом ядер, но низкой частотой - 2 - 2.2GHz не подходят для сетевых задач с низкими задержками. Низкая частота приводит к медленной обработке отдельно взятого пакета, которая не масштабируется с числом ядер. Иными словами, числом ядер невозможно побороть задержки в обработке пакетов.
Процессоры с большим числом ядер, но низкой частотой - 2 - 2.2GHz плохо подходят для сетевых задач с низкими задержками. Низкая частота приводит к медленной обработке отдельно взятого пакета.

Что с этим делать - лучше не покупать такие процессоры, они созданы для других задач. Если он уже куплен - поискать ему другое применение.


Оптимальная частота для процессоров используемых для сетевых задач - 3GHz+, но чем выше - тем лучше.

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


h2. Сетевые карты

{code}

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


Пример команд для увеличения буфера:

{code}

Альтернативный вариант с автоматическим определением оптимального значения (утилита из netutils-linux):

{code}
chroot /app/reductor/
rx-buffers-increase eth1
{code}

h3. Распределение прерываний
h4. Включение из консоли:

h4. Реальные прерывания
h5. Шаг 1. Выбрать пункт "Включить RSS для сетевых карт"

Хорошие сетевые карты поддерживают несколько очередей для входящих пакетов. Каждая очередь привязана к одному или нескольким ядрам. Несмотря на указанный список зачастую сетевые карты по умолчанию коробки работают на первом ядре процессора. Обойти это можно распределив прерывания c помощью утилиты rss-ladder.

{code}
rss-ladder eth1
menu->Reductor DPI X->Прочие настройки->Включить RSS для сетевых карт
{code}

Используйте разные ядра (cores), гипертрединг лучше выключить, с ним легко получить неоптимальные настройки.
Далее выйти с сохранением настроек.

h5. Многопроцессорные системы
h5. Шаг 2. Проверить запись в mirror_info.conf

Если в системе больше одного физического процессора, лучше распределять прерывания сетевой карты в пределах ядер её локальной NUMA-ноды. rss-ladder делает это автоматически. Число очередей лучше подстроить под число ядер одного физического процессора, по умолчанию их число часто равно общему числу ядер.
Открыть любым удобным для вас редактором ( например vim ) файл mirror_info.conf

Пример - поставим eth2 8 объединённых очередей.
{code}
vim /app/reductor/cfg/userinfo/mirror_info.conf
{code}

Убедиться в наличие соответствующей записи "mirror rss" напротив каждого указанного интерфейса.
{code}
ethtool -L eth2 combined 8
eth1 - - mirror rss
{code}

Очереди бывают combined или отдельные tx и rx, зависит от модели и драйвера сетевой карты.
h5. Шаг 3. Рестарт редуктора

Не все многопроцессорные системы поддерживают NUMA, иногда память является общей для обоих процессоров и для сетевых карт.

h5. Пример для Carbon Reductor 8

Мы не используем автоматическую настройку RSS, т.к. в редких ситуациях это приводит к зависанию сетевой карты. Так что настраивать это необходимо вручную:

Создаем сам файл-хук: `/app/reductor/cfg/userinfo/hooks/start.sh`

В него добавляем следующее содержимое:

{code}
#!/bin/bash

client_post_start_hook() {
rss-ladder eth0 || true
rss-ladder eth1 || true
}
/app/reductor/service restart
{code}

и делаем файл исполнимым: `chmod a+x /app/reductor/cfg/userinfo/hooks/start.sh`.

h4. Отложенные прерывания

{code}

В Carbon Reductor 8 данная утилита используется автоматически для сетевых карт с одной очередью.

h4. Комбинирование RSS и RPS
* Для 8 ядер - ff
* Для 12 ядер - fff
* Маску можно посмотреть в файле /sys/class/net/eth0/device/local_cpus

{note} {info}
Все примеры ниже - для 2х 6-ядерных процессоров
{note} {info}
\\

{code}
{code}

h4. Совместимость VLAN и RSS

Некоторые сетевые карты направляют все пакеты с одного VLAN в одну и ту же очередь, так как RSS hashing вычисляет один и тот же хэш для этих пакетов.

Некоторые карты умеют обрабатывать только VLAN первого уровня, но при использовании QinQ сталкиваются с той же проблемой.

Решения бывают разные:

* найти драйвера с поддержкой RSS+VLAN, сделанные сообществом.
* сменить сетевые карты на другую модель, которая поддерживает VLAN лучше.
* отказаться от VLAN, зеркалируя чистый трафик, без VLAN-тегов, либо снимать их при зеркалировании.
** в случае с QinQ может оказаться достаточно снять один тег.
* использовать распределение нагрузки с помощью RPS, используя для захвата одно ядро (экспериментальная опция fwboost: isolated rss).

h4. Большое число VLAN

При большом количестве VLAN создаётся большое количество правил iptables в цепочке iptables \-t raw \-nvL PREROUTING.

Их число можно сократить, перечислив через пробел интерфейсы с большим числом VLAN-тегов в опции: menu \-> Reductor DPI X \-> Настройки алгоритма фильтрации \-> Интерфейсы с большим количеством VLAN.

Опция позволяет добиться 1-3% прироста производительности.




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

Статья для лучшего понимания, правда больше под маршрутизаторы : [http://habrahabr.ru/post/108240/]




В кратце - можно за счёт повышения нагрузки на процессор слегка снять нагрузку с сетевой карты, уменьшая rx-usecs.

{code}
ethtool -K eth2 gro off
ethtool -K eth2 gso off
ethtool -K eth2 lro off
{code}
h3. NOTRACK

Эта технология отключает наблюдение за состоянием соединения для пакетов к которым она была применена. Это приводит к значительному снижению нагрузки на процессор в случае, если состояние соединения нас не интересует (захват трафика).
Эта опция включена по-умолчанию, выключать ее можно только в исключительных случаях.

Крупным провайдерам с большим объёмом трафика эта опция практически обязательна, почему - показывает пример:
Технология NOTRACK отключает наблюдение за состоянием соединения для пакетов к которым она была применена. Она приводит к значительному снижению нагрузки на процессор в случае, если состояние соединения нас не интересует (захват трафика).

h4. ДО включения:
Повышенная нагрузка может быть вызвана тем, что к сетевым картам, которые используются для приёма зеркала не применяется правило NOTRACK.

{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
{code}
Проверить это можно:
# посмотрев объёмы трафика по сетевым картам с помощью утилиты link-rate
# проверив, что все сетевые карты, принимающие зеркало трафика, имеют ссылку в цепочку mirror_traffic с помощью команды iptables \-t raw \-nvL PREROUTING

h4. ПОСЛЕ включения:

{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
{code}

h2. Сеть провайдера

h3. Масштабирование
h3. Отправлять меньше трафика

Проанализируйте что вы отправляете в зеркало. Возможно там есть что-то лишнее.

# Иногда один и тот же трафик попадает в зеркало дважды — инкапсулированным и чистым, в таком случае от инкапсулированного можно избавиться.
# Возможно отправляется трафик в обоих направлениях, а достаточно только исходящего.
# Возможно там есть лишние VLAN'ы с служебным трафиком, а Carbon Reductor анализирует только часть.
# Если зеркал трафика несколько, можно балансировать отправку, указывая порты коммутатора, с которых оно снимается (в случае "перекосов").

h3. Масштабирование

h4. В рамках одного сервера

h3. Flow-control

Для отправки зеркала рекомендуем отключать данную опцию, она чаще приводит к потерям, чем к сглаживанию пиковых нагрузок.
По умолчанию Carbon Reductor отключает flow-control для сетевых карт принимающих зеркало трафика, так как она чаще приводит к потерям, чем к сглаживанию пиковых нагрузок.

Проверить настройки можно с помощью команды:

{code}
ethtool -A eth2 rx off tx off
ethtool -a eth2
{code}

В Carbon Reductor 8 скоро будет доступно в автоматическом режиме.

h3. MTU

{code}

\**Перманентно*\* - *\*Постоянно\** \- дописать в настройки сетёвой карты `/etc/sysconfig/network-scripts/ifcfg-eth1`:

{code}
MTU=1540
{code}

h2. Carbon Reductor

h3. Опции снижающие производительность

- menu > настройки алгоритма фильтрации > логировать срабатывания
- menu > настройки алгоритма фильтрации > сохранять домен в адресе редиректа

Они замедляют процесс обработки пакета и отправки редиректов.