我正在测试两个工作站的网络性能,每个工作站都有 2.4GHz Xeon 四核处理器和 NC550SFP PCIe 双端口 10GbE 服务器适配器,背靠背连接。
我检查了 RAM 的带宽,约为 12Gbps,因此这里没有瓶颈。PCIe 总线速度也还可以。
我正在使用 UDP 的最小数据包大小测试最大 pps,结果与这些相比很糟糕:2012-lpc-networking-qdisc-fastabend.pdf(抱歉,我只能发布一个链接)。如果我增加数据包大小和 MTU,我可以获得接近线速(~9.9Gbps)。
我正在使用带有 NST 脚本的 pktgen、用于多个线程的 macvlan 接口,但只获得 ~1Mpps,所有四个核心都达到了 100%。
为了提高pktgen的TX性能,我偶然发现了这个文档: 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)
我得到了关于如何启用多个 TX 队列的提示Linux 网络堆栈的扩展:
支持多队列的 NIC 的驱动程序通常提供内核模块参数或指定要配置的硬件队列数。例如,在 bnx2x 驱动程序中,此参数称为 num_queues。如果设备支持足够的队列,则典型的 RSS 配置是为每个 CPU 配备一个接收队列,否则为每个内存域配备至少一个接收队列,其中内存域是一组共享特定内存级别(L1、L2、NUMA 节点等)的 CPU。
我查看了 Emulex 的 be2net 驱动程序文档,甚至给他们发了一封电子邮件,但毫无进展。我还浏览了内核源代码。
我在 Ubuntu 12.04 上获得了最新的内核版本(3.10),并且在 NIC 上安装了最新的固件。
有人有想法吗?
谢谢!
答案1
我在 Red Hat Enterprise Linux 机器上遇到了类似的挑战。我读了同一篇论文,并得出结论,我真正的问题是默认使用所有可能的 IRQ 让每个 CPU 参与网络数据包工作。我将 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 web 服务器和 10gbe,以便可以按预期实现严重的网络吞吐量:
apache cpuset,cpu apache/
下面是 cgconfig.conf 文件,它实际上将服务器与其余 CPU 活动分开:
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 hack),我测量到的网络吞吐量约为 5Gb/s。在 IRQ 集中且随机网络 IO 移开后,我使用 netperf 测量到接近线速(9.5Gb/s)的性能。
nb 巨型数据包没有任何区别,无论是之前还是之后的数字。