前情提要:
上文讲到我们在黑色星期五购物节拯救了美国的剁手族,所用的方法是临时禁用了一个第三方的网络包过滤模块,使得softirq的CPU使用率减少了20%,有惊无险地渡过了危机时刻。然而这只是权宜之计,我们在处理问题的过程中发现的很多性能隐患,最终都是要一一解决的。
前一篇《wakeup affinity》提到,手工关闭wakeup affinity之后8个NUMA节点的CPU负载变得更加均衡了。令人不由得想到为什么kernel进程调度器的负载均衡功能没有发挥作用?
Linux kernel通过scheduling domain来实现CPU的负载均衡,根据NUMA距离的远近组成一个树形结构,负载均衡算法沿着叶节点从下往上遍历,直到根domain,把进程从最忙的domain迁移到更空闲的domain。Linux kernel通过周期性地触发SCHED_SOFTIRQ来进行负载均衡操作。
在我们这个案例中,1号NUMA节点最为繁忙,理论上应该要负载均衡到其它节点,事实上我们观察到sched_softirq占用的CPU资源相当高,消耗的时间甚至比网卡的net_rx softirq还多:
然而尽管sched_softirq消耗的CPU资源不少,结果却不如人意,各NUMA节点的负载没有达到均衡。我本来以为关闭wakeup affinity之后、各NUMA节点之间的负载已经变得更加均衡的情况下,sched_softirq的开销也会降下来。然而并没有,sched_softirq仍然那么高!可以看到hot call trace如下,我也不知道是什么缘故,已经转给Linux原厂去研究。
walk_tg_tree_from+0x41 load_balance+0x34c rebalance_domains+0x152 run_rebalance_domains+0x55 __do_softirq+0xef call_softirq+0x1c do_softirq+0x65 irq_exit+0x115
但是从调优的角度,我们不必等研究结果出来,现在就有事情可以做,比如禁用load balance,方法是:
# disable SD_LOAD_BALANCE
for file in `find /proc/sys/kernel/sched_domain/* -name flags` ; do echo $((`cat $file` & 0xfffffffe)) >$file ; done
#enable SD_LOAD_BALANCE
for file in `find /proc/sys/kernel/sched_domain/* -name flags` ; do echo $((`cat $file` 0x1)) >$file ; done
测试结果相当不错,禁用load balance之后,sched_softirq的开销下降了许多:
IRQ Name Count ElpTime
7 SCHED 798328 1.532452
数据库响应时间也进一步从700多毫秒下降到了630毫秒,大约有10%的提高。
但是禁用load balance可能会有不可预测的影响,我们最终采取的方案不是禁用,而是增加load balance的周期min_interval和max_interval,也达到了差不多的效果。这两个参数在以下位置:
/proc/sys/kernel/sched_domain/cpu*/domain*/
未完,待续...
【问答时间】
网友提问:
有没有办法从os里查到网卡或者其他的pci/pcie设备是连的哪个numa node?
有两个方法:
通过sysfs:
"/sys/class/[device class]/[interface]/device/numa_node"
或者"/sys/devices/[PCI root]/[PCIe function]/numa_node"。
比如:# cat /sys/class/net/eth0/device/numa_node。
注意:需要BIOS支持,否则你可能看到numa_node的值为-1。
使用hwloc软件包。
安装hwloc.x86_64和hwloc-gui.x86_64。
命令是:# lstopo
赞 赏 码
领取专属 10元无门槛券
私享最新 技术干货