Я тестирую сетевую производительность двух рабочих станций, каждая из которых оснащена четырехъядерными процессорами Xeon 2,4 ГГц и двухпортовыми серверными адаптерами NC550SFP PCIe 10GbE, соединенными спина к спине.
Я проверил пропускную способность оперативной памяти, которая составляет ~ 12 Гбит / с, так что здесь нет узких мест. Скорость шины PCIe тоже в порядке.
Я тестирую максимальный pps, используя минимальный размер пакета для UDP, и результаты ужасны по сравнению с этими: 2012-lpc-network-qdisc-fastabend.pdf (извините, я могу опубликовать только одну ссылку). Если я увеличу размер пакета и MTU, я могу получить скорость, близкую к линейной (~ 9,9 Гбит / с).
Я использую pktgen со сценариями NST, интерфейсами macvlan для нескольких потоков и получаю только ~ 1 млн пакетов, все четыре ядра на 100%.
Чтобы улучшить производительность передачи pktgen, я наткнулся на этот документ: Масштабирование в сетевом стеке Linux
Я проверил, и да, у меня есть mq qdiscs, которые должны давать максимальную производительность:
# ip link list | grep eth3
5: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
Думаю, проблема в том, что используется только одна очередь TX:
# dmesg | grep be2net
[ 4.528058] be2net 0000:01:00.1: irq 47 for MSI/MSI-X
[ 4.528066] be2net 0000:01:00.1: irq 48 for MSI/MSI-X
[ 4.528073] be2net 0000:01:00.1: irq 49 for MSI/MSI-X
[ 4.528079] be2net 0000:01:00.1: irq 50 for MSI/MSI-X
[ 4.528104] be2net 0000:01:00.1: enabled 4 MSI-x vector(s)
[ 4.696026] be2net 0000:01:00.1: created 4 RSS queue(s) and 1 default RX queue
[ 4.761108] be2net 0000:01:00.1: created 1 TX queue(s)
Я получил подсказку, как включить несколько очередей передачи из Масштабирование в сетевом стеке Linux:
Драйвер для сетевой карты с поддержкой нескольких очередей обычно предоставляет параметр модуля ядра или указывает количество аппаратных очередей для настройки. В драйвере bnx2x, например, этот параметр называется num_queues. Типичная конфигурация RSS будет иметь одну очередь приема для каждого процессора, если устройство поддерживает достаточное количество очередей, или, в противном случае, по крайней мере, по одной для каждого домена памяти, где домен памяти представляет собой набор процессоров, которые совместно используют определенный уровень памяти (L1, L2 , Узел NUMA и т. Д.).
Я просмотрел всю документацию по драйверам be2net от Emulex, даже отправил им электронное письмо, но безуспешно. Я также просмотрел исходный код ядра.
У меня последняя версия ядра (3.10) на Ubuntu 12.04 с последней прошивкой на сетевых адаптерах.
Есть идеи?
Спасибо!
У меня была похожая (?) Проблема на Red Hat Enterprise Linux. Я прочитал ту же статью и пришел к выводу, что моя настоящая проблема заключалась в том, что по умолчанию я использую все возможные IRQ, чтобы задействовать каждый процессор в работе сетевых пакетов. Я сосредоточил активность IRQ на подмножестве доступных ядер, а затем соответствующим образом руководил работой. Вот файл rc.local:
# Reserve CPU0 as the default default IRQ handler
for IRQ in `grep eth0 /proc/interrupts | cut -d ':' -f 1`; do echo 2 > /proc/irq/$IRQ/smp_affinity; done
for IRQ in `grep eth1 /proc/interrupts | cut -d ':' -f 1`; do echo 2 > /proc/irq/$IRQ/smp_affinity; done
for IRQ in `grep eth2 /proc/interrupts | cut -d ':' -f 1`; do echo 2 > /proc/irq/$IRQ/smp_affinity; done
for IRQ in `grep eth4 /proc/interrupts | cut -d ':' -f 1`; do echo $(( (($IRQ & 1) + 1) << 2 )) > /proc/irq/$IRQ/smp_affinity; done
Вот файл cgrules.conf, который определяет / отличает мой веб-сервер apache от 10gbe, так что серьезная пропускная способность сети может произойти, как и предполагалось:
apache cpuset,cpu apache/
И вот файл cgconfig.conf, который фактически отделяет сервер от остальной активности процессора:
mount {
cpuset = /cgroup/cpuset;
cpu = /cgroup/cpu;
cpuacct = /cgroup/cpuacct;
memory = /cgroup/memory;
devices = /cgroup/devices;
freezer = /cgroup/freezer;
net_cls = /cgroup/net_cls;
blkio = /cgroup/blkio;
}
group apache {
cpuset {
cpuset.memory_spread_slab="0";
cpuset.memory_spread_page="0";
cpuset.memory_migrate="0";
cpuset.sched_relax_domain_level="-1";
cpuset.sched_load_balance="1";
cpuset.mem_hardwall="0";
cpuset.mem_exclusive="0";
cpuset.cpu_exclusive="0";
cpuset.mems="1";
cpuset.cpus="4-7,12-15";
}
}
group apache {
cpu {
cpu.rt_period_us="1000000";
cpu.rt_runtime_us="0";
cpu.cfs_period_us="100000";
cpu.cfs_quota_us="-1";
cpu.shares="1024";
}
}
В конфигурации по умолчанию (без взлома IRQ и cgroups) я измерил пропускную способность сети около 5 Гбит / с. Когда IRQ сконцентрированы, а случайный сетевой ввод-вывод удален, я измерил производительность, близкую к скорости передачи данных (9,5 Гбит / с), с помощью netperf.
n.b. пакеты большого размера не имели никакого значения ни до, ни после номера.