В производительность модуля фильтрация не упирается, как правило единственной проблемой при запуске бывает не совсем корректное работающее по умолчанию оборудование (процессор, сетевые карты). Мы много сталкивались с этим, поэтому готовы помочь с настройкой этого оборудования для обеспечения отличной производительности.
Есть три вещи которые в основном влияют на потерю пакетов при приёме (допустим, нас не волнует как долго он будет проходить через нашу систему, то есть latency мы можем жертвовать), а наша задача - поймать все пакеты, не упустив ни одного и обработать.
Итак, вещи:
- размер буфера сетевой карты
- правильное распределение прерываний входящих очередей сетёвки по ядрам
- мощность ядер процессора, обрабатывающего пакеты
- различные значения rx-usecs
Разберём их по порядку и набросаем пару костылей которые позволят вам заставить компуктир работать на полную мощь!
# Размер буфера сетевой карты
[root@centos ~]# ethtool -g eth1
Ring parameters for eth1:
Pre-set maximums:
RX: 4096
RX Mini: 0
RX Jumbo: 0
TX: 4096
Current hardware settings:
RX: 4096
RX Mini: 0
RX Jumbo: 0
TX: 256
Здесь мы видим выкрученный на максимум rx-буфер. По гуглу и описанию знакомых, значение RX-буфера по сути означает количество указателей на пакеты, которое сетевая карта может накопить до поступления прерывания по usecs'ам перед выплёвыванием далее в ядро. Подобрать значение довольно сложновато, ибо тут такая ситуация:
_Есть два стула, на одном задержки точеные, на другом потери мощные._
Иными словами высокое значение RX-буфера - задержки, низкое - потери. Вообще, недавно у нас в компании была дискуссия на эту тему, о том чем всё же по факту является значение Current HW Settings RX - реальным потолком буфера пакетов или значением при превышении которого необходимо сигнализировать о том, пора обрабатывать эти пакеты очень срочно, а на самом деле они могут копиться до Pre-set maximums. Внятных аргументов я не услышал, но пометочку о том, что надо почитать документацию и исходники на эту тему себе сделал.
Пример команды для увеличения буфера:
ethtool -G eth1 rx 4096
# Распределение прерываний
Многие сетевые карты имеют несколько очередей для входящих пакетов. Каждая очередь висит на ядре/списке ядер. На многих железках из коробки, несмотря на то, что в smp\_affinity\_list указан список 0-$cpucount все прерывания находятся на первом ядре процессора. Обойти это можно раскидав с помощью echo все прерывания на разные ядра.
По возможности используйте разные реальные ядра, допустим, дано:
- 1 процессор с гипертредингом
- 4 реальных ядра
- 8 виртуальных ядер
- 4 очереди сетевой карты, которые составляют 95% работы сервера
Раскинуть их на 0, 1, 2 и 3 ядра будет не так эффективно, как на 0, 2, 4 и 6.
Пример кода (костыльный и неуниверсальный), который раскидывает 8 очередей на 8 ядер (довольно простой случай).
#!/bin/bash
nic=eth1-TxRx-
cpucount=$(grep -c 'model name' /proc/cpuinfo)
grep $nic /proc/interrupts | while read irq $(eval echo cpu{1..$cpucount}) t queue t; do
irq=${irq//:}
/proc/irq/$irq/smp_affinity_list
echo "${queue##*TxRx-}" > /proc/irq/$irq/smp_affinity_list
done
# Мощность ядер процессора
[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
Суть видна - довольно мощный процессор работает в полсилы и даже не собирается напрягаться.
Заставить их напрячься можно так:
#!/bin/bash
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
# Различные значения rx-usecs
Не буду плодить энтропию, так что вот ссылка на хорошую статью (правда заточенную под маршрутизаторы больше): http://habrahabr.ru/post/108240/
В кратце - можно за счёт повышения нагрузки на процессор слегка снять напряги с сетёвки уменьшая. На большинстве машин использумых в моём случае оптимальным оказалось значение 1.
ethtool -C eth1 rx-usecs 1
Есть три вещи которые в основном влияют на потерю пакетов при приёме (допустим, нас не волнует как долго он будет проходить через нашу систему, то есть latency мы можем жертвовать), а наша задача - поймать все пакеты, не упустив ни одного и обработать.
Итак, вещи:
- размер буфера сетевой карты
- правильное распределение прерываний входящих очередей сетёвки по ядрам
- мощность ядер процессора, обрабатывающего пакеты
- различные значения rx-usecs
Разберём их по порядку и набросаем пару костылей которые позволят вам заставить компуктир работать на полную мощь!
# Размер буфера сетевой карты
[root@centos ~]# ethtool -g eth1
Ring parameters for eth1:
Pre-set maximums:
RX: 4096
RX Mini: 0
RX Jumbo: 0
TX: 4096
Current hardware settings:
RX: 4096
RX Mini: 0
RX Jumbo: 0
TX: 256
Здесь мы видим выкрученный на максимум rx-буфер. По гуглу и описанию знакомых, значение RX-буфера по сути означает количество указателей на пакеты, которое сетевая карта может накопить до поступления прерывания по usecs'ам перед выплёвыванием далее в ядро. Подобрать значение довольно сложновато, ибо тут такая ситуация:
_Есть два стула, на одном задержки точеные, на другом потери мощные._
Иными словами высокое значение RX-буфера - задержки, низкое - потери. Вообще, недавно у нас в компании была дискуссия на эту тему, о том чем всё же по факту является значение Current HW Settings RX - реальным потолком буфера пакетов или значением при превышении которого необходимо сигнализировать о том, пора обрабатывать эти пакеты очень срочно, а на самом деле они могут копиться до Pre-set maximums. Внятных аргументов я не услышал, но пометочку о том, что надо почитать документацию и исходники на эту тему себе сделал.
Пример команды для увеличения буфера:
ethtool -G eth1 rx 4096
# Распределение прерываний
Многие сетевые карты имеют несколько очередей для входящих пакетов. Каждая очередь висит на ядре/списке ядер. На многих железках из коробки, несмотря на то, что в smp\_affinity\_list указан список 0-$cpucount все прерывания находятся на первом ядре процессора. Обойти это можно раскидав с помощью echo все прерывания на разные ядра.
По возможности используйте разные реальные ядра, допустим, дано:
- 1 процессор с гипертредингом
- 4 реальных ядра
- 8 виртуальных ядер
- 4 очереди сетевой карты, которые составляют 95% работы сервера
Раскинуть их на 0, 1, 2 и 3 ядра будет не так эффективно, как на 0, 2, 4 и 6.
Пример кода (костыльный и неуниверсальный), который раскидывает 8 очередей на 8 ядер (довольно простой случай).
#!/bin/bash
nic=eth1-TxRx-
cpucount=$(grep -c 'model name' /proc/cpuinfo)
grep $nic /proc/interrupts | while read irq $(eval echo cpu{1..$cpucount}) t queue t; do
irq=${irq//:}
/proc/irq/$irq/smp_affinity_list
echo "${queue##*TxRx-}" > /proc/irq/$irq/smp_affinity_list
done
# Мощность ядер процессора
[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
Суть видна - довольно мощный процессор работает в полсилы и даже не собирается напрягаться.
Заставить их напрячься можно так:
#!/bin/bash
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
# Различные значения rx-usecs
Не буду плодить энтропию, так что вот ссылка на хорошую статью (правда заточенную под маршрутизаторы больше): http://habrahabr.ru/post/108240/
В кратце - можно за счёт повышения нагрузки на процессор слегка снять напряги с сетёвки уменьшая. На большинстве машин использумых в моём случае оптимальным оказалось значение 1.
ethtool -C eth1 rx-usecs 1