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

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

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

просмотр истории страницы
h1. Как увидеть информацию о потерях

Для начала убедимся в существовании проблемы. Для этого будем использовать набор утилит netutils-linux и стандартные инструменты iproute, в Carbon Reductor 8 они поставляются внутри контейнера `/app/reductor`, в других случаях установка происходит следующим образом:
Для начала убедимся в существовании проблемы. Для этого будем использовать набор утилит в Carbon Reductor и стандартные инструменты iproute.

{code} shell
yum -y install python-pip
pip install netutils-linux
Все команды надо запускать перейдя в контейнер Carbon Reductor:

{code}
chroot /app/reductor
{code}

h2. Информация о конкретной сетевой карте
Некоторые сетевые карты предоставляют подробную информацию о характере потерь:

{code} shell
ethtool -S eth2 | egrep rx_ | grep -v ': 0$' | egrep -v 'packets:|bytes:'
     rx_pkts_nic: 365565232680
Если нагрузка распределена неравномерно, т.е. Cpu0 трудится, а 1..n нет, то ресурсы процессора используются нерационально.

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

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

Вы можете посмотреть подробную информацию о том, как сетевой стек работает в текущий момент.
Просмотр подробной информации о текущем состоянии сетевого стека:

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

Он подсвечивает некоторые Некоторые значения подсвечиваются жёлтым (высокое значение) и красным (чрезвычайно высокое значение или ошибка). Это эвристика и не подстраивается под конкретный сервер.

При большом количестве ядер или сетевых карт информация может не влезать на экран, в таком случае можно уменьшить масштаб терминала или указать опцию `--devices=eth1,eth2,eth3`:
При количестве ядер больше 20 или большом числе VLAN информация может не влезать на экран, решение проблемы - уменьшить масштаб терминала или перечислить необходимые девайсы `--devices=eth1,eth2,eth3`:

Вывод выглядит так:

{code} shell
[root@reductor support]# network-top -n 1 --no-clear --no-color
# /proc/interrupts
{code}

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

h3. /proc/interrupts

Отображает то, как очереди сетевой карты распределены между ядрами. Наиболее оптимальный способ - 1 очередь на 1 ядро, можно "лесенкой". Бывает так, что в одну очередь приходит больше пакетов, чем в остальные - обычно это связано с тем, что трафик инкапсулирован (QinQ, PPP).
Отображает то, как очереди сетевой карты распределены между ядрами. Рекомендуем распределять 1 очередь на 1 ядро, можно "лесенкой".

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

h3. Load per CPU

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

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

h3. Network devices

Статистика по сетевым картам.

* rx-errors - общее число ошибок, обычно суммирует остальные. В какой счётчик попадает потерявшийся пакет зависит от драйвера сетевой карты.
* dropped, fifo, overrun - как правило, пакеты, не успевшие обработаться сетевым стеком
* missed - как правило, пакеты, не успевшие попасть в сетевой стек
* length - как правило слишком большие пакеты, которые не влезают в MTU на сетевой карте. Лечится его увеличением MTU.
* crc - прилетают битые пакеты. Часто бывает следствием - следствие высокой нагрузки на коммутатор.

h1. Что, как и когда настраивать
{code}

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

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

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

h3. DCA

Владельцам процессоров Intel Xeon и сетевых карт Intel 82599 (а также многих других 10Гбит/сек сетевых карт от Intel) стоит проверить настройки DCA в BIOS/UEFI, эта опция может дать приблизительно 5-10% производительности. Включен он или нет можно посмотреть командами (после запуска):

{code}
dmesg | egrep -i dca
{code}
Если включен, в выводе будет:

{code}
dca service started, version 1.8
{code}
Если выключен:

{code}
ioatdma 0000:00:08.0: DCA is disabled in BIOS
{code}

h3. Гипертрединг

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

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

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

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

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

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

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

RHEL-based дистрибутивы (платформа Carbon, CentOS, Fedora итд) позволяют указывать параметры ethtool в качестве опции в настройках интерфейса (`/etc/sysconfig/network-scripts/ifcfg-eth1`), например строчкой
В RHEL-based дистрибутивы (платформа Carbon, CentOS, Fedora итд) укажите параметры ethtool в настройках интерфейса (`/etc/sysconfig/network-scripts/ifcfg-eth1`) строчкой:

{code}
h4. Реальные прерывания

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

{code}
{code}

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

h5. Многопроцессорные системы

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

Пример - поставим eth2 8 объединённых очередей.

{code} shell
ethtool -L eth2 combined 8
{code}

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

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

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

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

h4. Комбинирование RSS и RPS

{note}
Перед настройками зафиксируйте средний рост потерь с помощью команды network-top ( chroot /app/reductor/ network-top ).

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

Оптимизация без замеров может ухудшить ситуацию\!
{note}

В случае если:

# Используется одна сетевая карта
# Сетевая карта не привязана к конкретной NUMA-ноде (команда cat /sys/class/net/eth0/device/numa_node выводит "-1")
# Система имеет 2\+ физических процессора
# Один процессор не справляется с нагрузкой
# При использовании распределения реальных прерываний по ядрам обоих процессоров потерь становится ещё больше


Можно попробовать комбинировать RSS и RPS.

Для RPS нужно явно указать маску перечисляющую все доступные процессоры.

* Для 4 ядер - f
* Для 8 ядер - ff
* Для 12 ядер - fff
* Маску можно посмотреть в файле /sys/class/net/eth0/device/local_cpus

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

{code}
chroot /app/reductor
rss-ladder eth0
autorps eth0 -m fff -f
{code}

Чтобы эффект сохранялся после перезагрузки нужно в хуке /app/reductor/cfg/userinfo/hooks/start.sh добавить следующее:


{code}
#!/bin/bash

client_post_start_hook() {
ethtool -L eth0 combined 6 || true
rss-ladder eth0 || true
autorps eth0 -m fff -f || true
return 0
}
{code}

Если ситуация стала хуже, RPS можно отключить, указав маску = 0:

{code}
autorps eth0 -f -m 0
{code}

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

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

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

На большинстве машин использумых в нашем случае оптимальным оказалось значение 1.

{code}
ethtool -C eth1 rx-usecs 1