网卡中断性能调优的一点记录
中文网络里面对于linux的网络性能调优这个话题有用的资料真的很少,分散在各家博客里面,只言片语并且没什么实际用例。说实话linux的网络性能真的不尽如人意,作为一个被大面积应用于服务器的系统内核,在默认参数下根本没办法负载很大的网络流量,不得不说是一件很坑爹的事情。
其中尤其是中断性能非常之低下。先看结论,在不存在任何调优选项的情况下,200M以上的的负载就有机会使linux网络中断超载,表面现象就是开始网络开始丢包,top可见某cpu使用率%sys非常高,有时候能看到ksoftirqd这个内核进程占用接近100%的使用率。但是在很简单的优化过后,就可以负载大得多的流量。
这里使用有机会这个词是因为实际情况还要考虑数据帧大小,越小的数据帧对系统压力越大。为什么网络性能存在瓶颈这里就不详细说了,放上一篇参考文章。
Linux转发性能评估与优化 这篇文章从内核实现上把性能问题的存在讲得很清楚了。
这里只讨论在已有的技术下,优化中断性能的两个方案。第一个是RSS,俗称网卡多队列。
RSS需要网卡硬件支持,好在现在大部分服务器网卡都是支持RSS的。也有少部分例外,比如某些e1000e的板载千兆网卡就不支持。如果网卡支持RSS,那么驱动程序在默认情况下会开启这个特性。本来,如果多个队列绑定到多个CPU上自然就能减轻中断负载对单一核心的压力,可惜萌傻的linux核心默认把多队列全绑在cpu0上。
红帽系的发行版开启irqbalance这个服务就可以根据负载均衡队列了,建议开启简单方便。有些极端负载情况下需要自行指定,方法也很简单,检查/proc/interrupts
文件可以得到网卡队列对应的中断号,假如是88,我需要将其绑定到cpu8上,执行如下命令echo 8 > /proc/irq/88/smp_affinity_list
。
另一个可用的技术是RPS,强调一下某些博客所说的RPS是RSS的软实现是错误的。RPS的做法就是,哪个cpu上的中断,哪个cpu去处理,这是一种调度策略,与RSS是截然不同的。在极端情况下RPS可以获得非常好的性能,可惜实际情况下反而对整机整体负载有所妨害,主要是进程调度导致的cpu缓存丢失导致,所以在应用负载已经非常高的情况下开启RPS是没意义的做法(开启RFS会稍微好转但是作用也不大)。下图所示为开启RSS不开启RPS的情况。
可见左侧cpu存在较高的%sys负载,是因为网卡队列都绑定在左侧的几个cpu上。下图所示为同时开启RPS的情况。
可见%sys较为均衡,同时整机负载略有上升。顺便强调一点纯转发工作负载下RPS没有太大作用,想想RPS的原理就知道了。纯转发工作负载下linux的性能表现更为不堪,附上一张转发负载约为300M的top图压压惊。
开启了RSS,eth0的8个队列绑定在cpu0-7,eth1的8个队列绑定在cpu8-15,看起来已经半载有多了,也就是说性能瓶颈会出现在500M左右的时候,非常的吓人。