我正在尝试使用一台旧的 Fujitsi RX300S2,配备四核 Intel Xeon CPU @2.80GHz 作为 Gitabit NAT 路由器,它有一个通过 PCI-X 连接的双千兆 NIC。
路由器还会将多播流量从外部接口转发到内部网络。多播路由由上游 Cisco 路由器处理,因此 NAT 路由器只需在 eth1(上游)和 eth0(内部)之间“泄露”多播流量。
这已使用 igmpproxy 正确设置,它基本上使 L3 路由器根据多播流量充当 L2 桥。
在测试吞吐量时,我可以轻松接收 200 个组/流(约 80'000 p/s)上的 ~850-900Mbit 多播流量到用户空间中的本地进程,该进程还可以实时分析 200 个流而不会丢失数据包。本地进程将一个核心的最大利用率设为 100%。
该流由封装在 IP UDP 数据包中的 IPTV mpeg 传输流组成。7x188=1316 字节的有效负载。
但是在转发模式下测试吞吐量时,例如多播流量进入 eth1 并在内核级路由到 eth0 并发送到本地网络,NAT 路由器无法转发所有接收到的流量。
外部接口 eth1 接收所有多播流量~900Mbit,但传出接口仅传输~600Mbit,并且根据连接到 eth0 的接收测试机器,所有流都遭受数据包丢失。
当分析负载时,ksoftirqd/3 的最大 CPU 利用率为 100%,但其他 3 个核心的 CPU 利用率低于 10%,因此似乎并非所有 4 个核心都参与了负载。
/proc/interrupts 还显示 eth0 和 eth1 共享 irq16:
CPU0 CPU1 CPU2 CPU3
16: 0 0 92155 208280892 IO-APIC 16-fasteoi uhci_hcd:usb2, uhci_hcd:usb5, eth1, eth0
可以看出,CPU3 处理了过多的中断。
我阅读了有关 cpu_affinity 的各种文章,并尝试将 CPU 核心固定到网络队列。不幸的是,这款 Broadcom 的 NIC tg3 不支持多个队列,但仍然应该可以在这个四核系统上的更多核心之间共享负载。
或者是 PCI-X 总线是瓶颈,但如果是这样,那么传入 eth1 和传出 eth0 的吞吐量都应该减少,并且数据包应该被丢弃eth1,但似乎 eth1 和 eth0 之间数据包丢失了。事实并非如此,因为当数据包在路由器中丢失时,/sys/class/net/eth1/statistics/rx_missed_errors 会大量增加(大约 1000 p/s)。
当只有 100 个通道和大约 500 Mbit 被转发时,不会发生数据包丢失,并且 ksoftirqd/3 仅消耗大约 5-6% 的 CPU。但是当转发 600Mbit 时,ksoftirqd/3 消耗 100%,因此似乎遇到了 CPU 之外的一些瓶颈。
像这样的旧服务器是否只能在两个内置 NIC 之间单向转发 1Gbit 的 UDP 流量?即使数据包很大,有效载荷为 1316 字节,在 1Gbit 中也能达到中等的 80..90kp/s?
答案1
我们放弃了这台服务器,因为根据规格,两个板载网络接口不应该承载全千兆流量。第二个接口用于管理。
配备 PCIe 和两个 Intel i210 千兆适配器的标准台式机酷睿 i5 能够毫无问题地转发 1Gbit 多播 UDP 流量。
不过,由于流量突发,它需要调整 RX 和 TX 缓冲区 (ethtool -G)。2x 或 4x PCIe 可能有助于降低 PCIe 总线拥塞导致丢失数据包的风险。