numa节点间CPU利用率不均衡 - wakeup affinity

最近遇到服务器numa节点间cpu利用率不均衡,清除sched_domain的flags中的AFFINE_WAKEUPS标志位是一个优化方法。但是如果直接将AFFINE_WAKEUPS关闭,将无法充分利用L2、L3 cache缓存命中带来的性能提升以及内存访问性能。

这还是要根据当前系统运行情况而定,例如在第二篇文章提到,如果在numa系统上,一个numa node利用率非常高,比如高于90%,而另一个node利用率可能只有60%~70%,这时可以尝试disable wakeup affinity,因为此时系统cpu利用率已经很高了(90%以上),相较于打开AFFINE_WAKEUPS所带来的缓存命中与内存访问的性能提升,高cpu利用率所导致的调度延迟所带来的影响更大。所以关闭AFFINE_WAKEUPS,使所有numa node的cpu利用率均衡起来,调度延迟会降低,尽管会带来缓存命中与内存访问的性能下降,但是两害取其轻才是重点。

下面是三篇相关AFFINE_WAKEUPS技术讨论的文章:

1, Wakeup Affinity | 我的黑色星期五(3)

Linux的进程调度有一个不太为人熟知的特性,叫做wakeup affinity,它的初衷是这样的:如果两个进程频繁互动,那么它们很有可能共享同样的数据,把它们放到亲缘性更近的scheduling domain有助于提高缓存和内存的访问性能,所以当一个进程唤醒另一个的时候,被唤醒的进程可能会被放到相同的CPU core或者相同的NUMA节点上。这个特性缺省是打开的,它有时候很有用,但有时候却对性能有伤害作用。设想这样一个应用场景:一个主进程给成百上千个辅进程派发任务,这成百上千个辅进程被唤醒后被安排到与主进程相同的CPU core或者NUMA节点上,就会导致负载严重失衡,CPU忙的忙死、闲的闲死,造成性能下降。

Wakeup affinity特性在中断唤醒进程时也起作用,在我们这个案例中,服务器有8个NUMA节点,只有一块网卡承担着所有的流量,网卡与1号NUMA节点最近,所有的网络中断都分配给1号NUMA节点的CPU去处理,当中断处理完成时,由于wakeup affinity特性的作用,所唤醒的用户进程也被安排给1号NUMA节点,导致1号NUMA节点的的负载非常高,结果就如前一篇《run queue latency》所阐述的,用户进程运行在1号NUMA节点上产生了很大的延迟,客户感觉到响应变慢。

Wakeup affinity特性对超配的KVM虚拟机也有负面的性能影响,参见https://lkml.org/lkml/2010/4/11/108

Wakeup affinity特性是可以手工关闭的,方法是清除/proc中sched_domain的flags中的AFFINE_WAKEUPS标志位,由于sched_domain有很多,所以最好写个脚本来做,比如:

# disable AFFINE_WAKEUPS

for file in `find /proc/sys/kernel/sched_domain/* -name flags` ; do echo $((`cat $file` & 0xffffffdf)) >$file ; done

#enable AFFINE_WAKEUPS

for file in `find /proc/sys/kernel/sched_domain/* -name flags` ; do echo $((`cat $file` | 0x20)) >$file ; done

在我们这个案例中,关闭wakeup affinity之后的效果比较明显,测试结果是8个NUMA节点的负载变得更加均衡了,应用的响应时间从最初的800-1000毫秒下降到700多毫秒。

2, https://nanxiao.me/linux-kernel-note-60-scheduling-domain/

NUMA系统上,由于不同CPU直接访问本地内存和远端内存的时间相差很大,所以更好地调度算法就显得很重要。Linux kernel引入了scheduling domain的概念。可以参看下面例子:

[root@localhost ~]# cd /proc/sys/kernel/sched_domain/
[root@localhost sched_domain]# ls
cpu0  cpu1  cpu2  cpu3  cpu4  cpu5  cpu6  cpu7
[root@localhost sched_domain]# ls -alt *
cpu0:
total 0
dr-xr-xr-x. 1 root root 0 Feb 26 19:37 domain0
dr-xr-xr-x. 1 root root 0 Feb 26 19:37 domain1
dr-xr-xr-x. 1 root root 0 Feb 26 19:37 .
dr-xr-xr-x. 1 root root 0 Feb 26 19:37 ..

cpu1:
total 0
dr-xr-xr-x. 1 root root 0 Feb 26 20:06 domain0
dr-xr-xr-x. 1 root root 0 Feb 26 20:06 domain1
dr-xr-xr-x. 1 root root 0 Feb 26 19:37 .
dr-xr-xr-x. 1 root root 0 Feb 26 19:37 ..

cpu2:
total 0
dr-xr-xr-x. 1 root root 0 Feb 26 20:06 domain0
dr-xr-xr-x. 1 root root 0 Feb 26 20:06 domain1
dr-xr-xr-x. 1 root root 0 Feb 26 19:37 .
dr-xr-xr-x. 1 root root 0 Feb 26 19:37 ..

... ...

cpu7:
total 0
dr-xr-xr-x. 1 root root 0 Feb 26 20:06 domain0
dr-xr-xr-x. 1 root root 0 Feb 26 20:06 domain1
dr-xr-xr-x. 1 root root 0 Feb 26 19:37 .
dr-xr-xr-x. 1 root root 0 Feb 26 19:37 ..

/proc/sys/kernel/sched_domain/目录下每个CPU都有一个自己的目录,并且每个CPU目录下都有和自己相关的domain信息。

multi-level系统中,也拥有multi-levelscheduling domain(内核中结构体是struct sched_domain)。每个scheduling domain包含一组共享属性和调度策略的CPU;每个scheduling domain包含至少一个或多个CPU group(内核中结构体是struct sched_group),每个CPU group会被scheduling domain看做一个独立的单元。

scheduling domain的核心代码位于kernel\sched\core.c中,关于/proc/sys/kernel/sched_domain/cpu$/domain$中各个文件的含义,都可以在这里找到。

NUMA系统上,如果一个node利用率非常高,比如高于90%,而另一个node利用率可能只有60%~70%,这时可以尝试disable wakeup affinity

参考资料:
Scheduling domains
sched-domains.txt
Does domain0 in /proc/sys/kernel/sched_domain/cpu$ refer top-level domain in the system?
How to understan /proc/sys/kernel/sched_domain/cpu$/domain$/flags?

3,Redis 高负载下的中断优化

https://blog.csdn.net/meituantech/article/details/80062289

NUMA 架构下的中断优化
这时我们再回归到中断的问题上,当两个NUMA节点处理中断时,CPU实例化的softnet_data以及驱动分配的sk_buffer都可能是跨node的,数据接收后对上层应用Redis来说,跨node访问的几率也大大提高,并且无法充分利用L2、L3 cache,增加了延时。

同时,由于Linux wake affinity 特性,如果两个进程频繁互动,调度系统会觉得它们很有可能共享同样的数据,把它们放到同一CPU核心或NUMA Node有助于提高缓存和内存的访问性能,所以当一个进程唤醒另一个的时候,被唤醒的进程可能会被放到相同的CPU core或者相同的NUMA节点上。此特性对中断唤醒进程时也起作用,在上一节所述的现象中,所有的网络中断都分配给CPU 0去处理,当中断处理完成时,由于wakeup affinity特性的作用,所唤醒的用户进程也被安排给CPU 0或其所在的numa节点上其他core。而当两个NUMA node处理中断时,这种调度特性有可能导致Redis进程在CPU core之间频繁迁移,造成性能损失。

综合上述,将中断都分配在同一NUMA Node中,中断处理函数和应用程序充分利用同NUMA下的L2、L3缓存、以及同node下的内存,结合调度系统的wake affinity特性,能够更进一步降低延迟。

SMP 架构
随着单核CPU的频率在制造工艺上的瓶颈,CPU制造商的发展方向也由纵向变为横向:从CPU频率转为每瓦性能。CPU也就从单核频率时代过渡到多核性能协调。

SMP(对称多处理结构):即CPU共享所有资源,例如总线、内存、IO等。

SMP 结构:一个物理CPU可以有多个物理Core,每个Core又可以有多个硬件线程。即:每个HT有一个独立的L1 cache,同一个Core下的HT共享L2 cache,同一个物理CPU下的多个core共享L3 cache。

下图(摘自内核月谈)中,一个x86 CPU有4个物理Core,每个Core有两个HT(Hyper Thread)。图:https://mp.weixin.qq.com/s/y1NSE5xdh8Nt5hlmK0E8Og

NUMA 架构
在前面的FSB(前端系统总线)结构中,当CPU不断增长的情况下,共享的系统总线就会因为资源竞争(多核争抢总线资源以访问北桥上的内存)而出现扩展和性能问题。

在这样的背景下,基于SMP架构上的优化,设计出了NUMA(Non-Uniform Memory Access)—— 非均匀内存访问。

内存控制器芯片被集成到处理器内部,多个处理器通过QPI链路相连,DRAM也就有了远近之分。(如下图所示:摘自CPU Cache)

CPU 多层Cache的性能差异是很巨大的,比如:L1的访问时长1ns,L2的时长3ns...跨node的访问会有几十甚至上百倍的性能损耗。

发布了158 篇原创文章 · 获赞 115 · 访问量 37万+

猜你喜欢

转载自blog.csdn.net/yiyeguzhou100/article/details/103656664