对于tx方向,发包使用的cpu和队列可以通过taskset和xps指定.
tx完成的中断则通过中断亲和性绑定:
echo 8 > /proc/irq/<tx-irq-number>/smp_affinity
taskset -c 2 ./your_server`
将你的发包进程绑定在 CPU 2,那么所有 send()
都会在 CPU 2 上执行,TX 流量也就自然从 CPU 2 发出。
这是最直接、最常见的方法,也是高性能多核服务器中常用的做法。
XPS
(Transmit Packet Steering)XPS 是 Linux 提供的一种优化机制,用于将不同 CPU 发起的 TX 操作 映射到特定的 TX 队列。
ls /sys/class/net/eth0/queues/tx-*/xps_cpus`
你可以为每个 TX queue 设置允许哪个 CPU 使用:
# 将 tx-0 绑定到 CPU0
echo 1 > /sys/class/net/eth0/queues/tx-0/xps_cpus
将 tx-1 绑定到 CPU1
echo 2 > /sys/class/net/eth0/queues/tx-1/xps_cpus`
其中1,2为cpu位图,即1代表0001, 2代表0010
SO_BINDTODEVICE
/ 多 socket / BPF更高级的策略可以用:
SO_BINDTODEVICE
强制走特定网卡;
SO_REUSEPORT
来实现 CPU-based socket 路由;
AF_XDP
实现用户态发包 → 硬件队列映射(完全由你控制 TX ring)。EBPF不太了解.待研究...
RX方向通过绑定流到队列,然后将队列中断绑定到对应cpu实现了流和中断cpu的绑定,然后中断cpu在完成skb建立后会触发对应cpu的软中断,上处理协议栈流程,最后送到socket进行应用层处理.
# 查看中断在 CPU 分布 (硬中断的cpu)
cat /proc/interrupts | grep eth0
# 查看软中断执行在哪些 CPU 上 (软中断的cpu)
cat /proc/softirqs | grep NET_RX
在ARS(auto-receive-scaling)中,流的txrx队列是对称的,所以只需要将之前tx方向配置的队列队列的rx队列的中断和软中断绑定到和tx绑定的cpu即可实现应用的tx和rx方向使用同一cpu处理.
grep eth0 /proc/interrupts`
echo 2 > /proc/irq/XX/smp_affinity # 绑定队列中断到 CPU 1`
echo 2 > /sys/class/net/eth0/queues/rx-0/rps_cpus # 配置队列软中断到 cpu 1
对于ARS来说,如果一个流是单向的(server模式),首包会随机到一个rx队列,然后tx方向则通过选定的cpu的tx队列发送,后续的包则通过tx对应的rx队列来收包,rx队列环形对应的irq cpu完成中断收包,xps绑定的中断cpu进行协议栈收包,收包处理,整个流程中,流处理能很快收敛到同一个cpu上.
RSS将流量根据五元组or三元组(only ip)hash值和间接表得出对应的rx队列,理论上只是负载均衡的手段,无法控制某个流固定绑定在固定队列上,也就是说没办法将流量和队列绑定到对应的中断cpu上.
因此我们只能尝试使用aRFS(auto-receive-flow-scaling)将流的软中断cpu配置成和应用处理的cpu一致,来提升cpu的cache命中率;
如果网卡支持3中的ntuple等基于流量的队列控制,那aRFS通过下发硬件流表的形式让网卡硬件将该流量送到与软中断相同cpu对应的硬件队列上去,从而实现完整的rx流cpu亲和性全自动绑定.
需要注意的是aRFS不会更改收包硬中断的cpu,如果rps和irq affinity对于同一队列的cpu绑定不一样,需要手动将对应队列的irq affinity设置和rps保持一致.
aRFS明显可以利用硬件上报的网卡hash值进行分流
ethtool -k eth0 | grep ntuple # 确定网卡是否支持ntuple
aRFS配置方法:
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries # 启用aRFS并设置最大缓存流数量
echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus # f = CPU 0~3 需要设定为需要的值
ntuple 和flow director可以将确定的流送到指定的队列,然后通过队列irq和cpu绑定,能实现流和中断cpu的绑定,然后使用RPS将队列和软中断cpu绑定,从而让流处理在同一个cpu处理,和2中方法相比,如果没有启用aRFS,属于是手动配置.
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。