这是一篇个人认为非常非常厉害的文章,取自这里。讲述了如何提升UDP流的处理速率,但实际涉及的技术点不仅仅限于UDP。这篇文章中涉及的技术正好可以把前段时间了解的知识串联起来。作者:Toshiaki Makita
Toshiaki Makita
因特网上UDP事务
以太网带宽和交互
需要处理多少交互
TSO/GSO/GRO
TSO/GSO用于发送报文时,将上层聚合的数据进行分割,分割为不大于MTU的报文;GRO在接受侧,将多个报文聚合为一个数据,上送给协议栈。总之就是将报文的处理下移到了网卡上,减少了网络栈的负担。TSO/GSO等可以增加网络吞吐量,但有可能造成某些连接上的网络延迟。
RSS
RSS是物理网卡支持的特性,可以将NIC的多个队列映射到多个CPU核上进行处理,增加处理的效率,减少CPU中断竞争。
启用RSS的NIC的性能
recvfrom()
和sendto()
服务器进行测试确认瓶颈
sar -u ALL -P ALL 1
可以在/proc/zoneinfo中查看NUMA的node信息。使用mpstat也可以看到类似的现象,
%irq
表示硬中断,%soft
表示软中断。
RSS下的softirq
/proc/irq/<irq>/smp_affinity
确定
RSS会将报文分发到不同的队列,smp_affinity会设置中断亲和性,将不同队列产生的中断上送给不同的CPU核。
irqbalance
设置smp_affinity
校验smp_affinity
irqbalance
仅使用了Node 0(核0-4, 10-14),如何修改?
检查affinity_hint
affinity_hint
affinity_hint
是均匀分布的
irqbalance
(通过/etc/sysconfig/irqbalance)中添加"-h exact"选项
修改irqbalance选项
irqbalance
服务
sar -u ALL -P ALL 1
检查rx-queue状态
RSS 间接表
使用RPS
# echo 10040 > /sys/class/net/ens1f0/queues/rx-6/rps_cpus
# echo 20080 > /sys/class/net/ens1f0/queues/rx-7/rps_cpus
# echo 40100 > /sys/class/net/ens1f0/queues/rx-8/rps_cpus
# echo 80200 > /sys/class/net/ens1f0/queues/rx-9/rps_cpus
sar -u ALL -P ALL 1
RSS & affinity_hint & RPS
变的更差了。。
分析软中断
perf record -a -g -- sleep 5
perf.data
文件perf.data
queued_spin_lock_slowpath
:锁竞争
udp_queue_rcv_skb
:要求socket锁
socket锁竞争
避免锁竞争
SO_REUSEPORT
选项分割sockets 使用SO_REUSEPORT
sar -u ALL -P ALL 1
SO_REUSEPORT
默认使用流哈希来选择队列,不同的CPU核可能会选择相同的sockets,导致竞争。
避免socket锁竞争
SO_ATTACH_REUSEPORT_CBPF/EBPF
实现SO_ATTACH_REUSEPORT_EPBF
前后的火焰图如下,可以看到中断消耗的CPU更少了
固定用户线程
输出方向的锁
Tx队列
pfifo_fast
)Tx队列的锁竞争
避免Tx队列的锁竞争
ixgbe
(Intel 10GbE NIC驱动)可以自动设置XPSXPS的影响如何
重新启用XPS
优化单个核 1
禁用GRO
优化单个核 2
优化单个核3
优化单个核4
优化单个核5
超线程
更多热点1
更多热点2
其他挑战
总结
SO_REUSEPORT
SO_ATTACH_REUSEPORT_EBPF/CBPF