前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >极致性能(1):以NUMA为起点

极致性能(1):以NUMA为起点

作者头像
boypoo
发布2020-02-14 14:00:41
3.7K0
发布2020-02-14 14:00:41
举报
文章被收录于专栏:数据工人数据工人

(1)

一个[合格的]Oracle DBA在安装数据库的时候,通常都会按要求关闭NUMA(MOS:Disable NUMA At OS Level (Doc ID 2193586.1)),因为启用NUMA会导致CPU彪高,性能很差(MOS:High CPU Usage when NUMA enabled (Doc ID 953733.1))。也许是这类问题太多,从Oracle 11gR2开始,默认就关闭了NUMA特性,因为NUMA的使用比较苛刻,要结合硬件、操作系统和Oracle版本(MOS:Oracle NUMA Usage Recommendation (Doc ID 759565.1))以及应用程序。稍有不对,努力白费,所以乖乖的关掉NUMA,是比较正确的事情。

同时还搞了个隐含参数来应对想用NUMA的人(还有几个类似的NUMA隐含参数,谨慎对待):

_enable_NUMA_support=TRUE

还特意加了强调:

Recommendation:

· Customers who have tuned their Database specifically for NUMA can continue to run with NUMA enabled with Oracle Server Version 11.2.0.1.

· It is strongly recommended to customers who want to enable NUMA do sufficient testing before going into production.

这也没辙,O记实在是被NUMA搞怕了(Doc ID 759565.1):

如何检验NUMA特性被禁用了:

# numactl -H

available: 1 nodes (0)

node 0 size: 4195 MB

node 0 free: 3304 MB

node distances:

node 0

0: 10

不然可能至少有2个node。

(2)

那NUMA到底是啥玩意呢?

要搞清楚其实不太容易,要花点时间。

从硬件的角度来看,NUMA(non-uniform memory access,非一致性内存访问)是一个计算机平台,它包含多个组件/集成片,每个组件/集成片包含多个CPU、本地内存和I/O总线。为简洁起见,并从软件抽象中消除对这些物理组件/集成片的硬件视图的歧义,后续给了这些组件/集成片一个统一的名字,称为socket。

每个socket都可以看作是SMP对称多处理器的子集——独立SMP系统所需的某些组件可能不会放到socket上。NUMA系统的socket通过某种系统互连连接在一起,例如,交叉或点对点链路是NUMA系统互连的常见类型。这两种类型的互连可以聚合在一起,以创建与其他socket具有多个距离的socket的NUMA平台(这句话有点绕,在启用NUMA的OS里,你用numactl -H命令看到输出的distances部分,就大概明白这句话的意思了)。

这是一个4-way的物理的服务器主板图。看到右侧4个黄色标签的东东了么,这就是一个socket了,离它最近的那4根内存条就是它的了。通常我们一般就还有一个socket,带4根内存条,那就是传统的SMP架构。

上2张逻辑抽象图片,可能更清晰一些。第一章图例有显示node0的CPU可能会去访问node2的memory,这就会造成某些业务的性能影响或者是抖动。

分别是2-way 8cores CPU的NUMA架构和4-way 24cores 的NUMA架构。所谓的非一致内存访问NUMA,就是指这里的local access和remote access了,它们的路径长短不一样,成不不一样,所以是非一致的。

需要注意的是,上面图中的node,事实上是Linux系统中的一个逻辑概念,跟硬件层面的socket对应,也可以混用。

对于Linux系统,感兴趣的是NUMA平台所谓的Cache Coherent NUMA或ccNUMA系统。在ccNUMA系统中,所有的内存对连接到任何socket的任何cpu都是可见的和可访问的,并且高速缓存的一致性由处理器高速缓存和系统互连在硬件中处理。

内存访问时间和有效内存带宽取决于包含CPU/IO总线的socket到包含目标memory的socket之间的距离。例如,通过连接到同一个socket的CPU访问内存将比访问其他远程socket上的内存更快,带宽更高。

NUMA硬件提供商并不构建NUMA系统。这种架构是一种提供可伸缩内存带宽的方法。然而,为了实现可伸缩的内存带宽,系统和应用软件必须将大部分内存使用安排为“本地”内存(即则为同一socket上的内存)或与内存最接近的socket。

因此,Linux系统将NUMA的硬件资源划分为多个称为node的软件抽象。Linux将node映射到硬件平台的物理socket上,为这个体系架构抽象出一些细节。跟物理socket一样,软件node可以包含0个或多个CPU、内存和I/O总线。访问“更近”node上的内存(即映射到更近的socket的node)通常比访问更远的socket会得到更快的访问时间和更高的有效带宽。

对于某些体系结构(如x86),Linux会“隐藏”表示附加内存的socket上的node,并将附加到该socket的任何CPU重新分配给表示具有内存的socet(node)。因此,在这些体系结构中,不能假定linux与给定node关联的所有cpu都将看到相同的本地内存访问时间和带宽。

另外,对于某些体系结构(如x86),linux支持模拟其他node。对于NUMA仿真,Linux将把现有的node(或者非NUMA平台的系统内存)分割成多个node。每个模拟node将管理底层socket的一小部分物理内存。NUMA emluation对于在非numa平台上测试NUMA内核和应用程序特性以及与cpusets一起使用时作为一种内存资源管理机制非常有用。

每个有内存的node,Linux构建了一个独立的内存管理子系统,包括自己的空闲页面列表、正在使用的页面列表、使用统计信息和锁,以斡旋(mediate)访问。此外,Linux为每个内存区域(dma、dma32、normal、high_memory、movable中的一个或多个)构造一个有序的“zonelist”。当选定的区域/node无法满足分配请求时,Zonelist会指定某个区域/node供访问。当区域没有可用内存来满足请求时,这种情况称为“overflow”或“fallback”。这个过程,其实就是一个斡旋的过程。

系统管理员和应用程序设计人员可以使用各种CPU关联命令行接口(如taskset和numactl)以及程序接口(如sched_setaffinity)限制任务的迁移,以改进NUMA局部性,让特定业务获得更好性能。还可以使用Linux NUMA内存策略修改内核的默认本地分配行为。

系统管理员可以使用控制组和CPUset 限制非特权用户在调度函数时使用指定的CPU和node内存。

(借用一张图)

在本图中,node0/node1的内存大小都是32GB,每个node上有10颗CPU。这里的CPU,如果你用cat /etc/interrupts看的话,会显示为Core.

在《NUMA Best Practices for Dell PowerEdge 12th Generation Servers》(P13,2012)一书中,有这么一张图,这里的一个socket上有2个node,它是AMD处理器。

(3)来看看

HPE Proliant系列的NUMA情况。

Linux Kernel从2.6开始支持ccNUMA系统,目前最新的已经是Kernel 5了,虽然RHEL 7.x还用的是3.10。

我们可以看到,因为采用了交叉互联架构,所以除了访问本地内存之外,其他node上的内存的距离是一样的。

但就算是距离一样,其实跨节点的内存访问的带宽并非是一样的,而且各个型号都不一样。DL580服务器( DL580 G7 with 2.40 GHz ten core Xeon E7 4870)各node间内存访问的带宽:

DL560、DL585的NUMA架构跟DL580又不太一样,各node间内存访问带宽又会有差别。这里的0.52/0.34,是指带宽相当于本地带宽的52%。DL580 Gen10比DL560会好一些,是0.47/0.44。

可以用语句numactl实测访问不同node的内存的带宽,下面是个示例:

# numactl --cpubind=0 --membind=0 dd if=/dev/zero of=/dev/shm/A bs=1M count=1024

1024+0 records in

1024+0 records out

1073741824 bytes (1.1 GB) copied, 0.823497 s, 1.3 GB/s

# numactl --cpubind=0 --membind=1 dd if=/dev/zero of=/dev/shm/A bs=1M count=1024

1024+0 records in

1024+0 records out

1073741824 bytes (1.1 GB) copied, 0.936182 s, 1.1 GB/s

虽然差距不是很大,还是要尽量避免跨节点访问内存。

那么怎么避免node0的内存溢出导致node外分配呢?

如前面在第(2)节所描述的,当策略选择的node无法满足请求时,除绑定模式(membind)外,所有Linux内存策略模式都允许分配溢出(overlow)或退回(fallback)到其他节点,通过SLIT(系统局部信息表)斡旋。

Linux 使用内核参数vm.zone_reclaim_mode来控制node溢出。

当vm.zone_reclaim_mode被禁用或为零时,内核将溢出到目标node区域列表中的下一个node。

启用vm.zone_reclaim_模式时,内核在离开目标node进行分配之前尝试从目标node的内存中释放或回收页面。相当于是多一次机会。

当所有异地node的距离都是20时,默认是disable的。启用还是不启用呢?通过应用实际测试后再定。

(4) HPE Proliant Gen10的设置

首先是BIOS中,“NUMA Group Size Optimization”,默认是“clustered”,但如果应用设计的时候没有考虑到使用跨多组处理器的使用,那么就建议选择“flat”。

Linux将每个NUMA node包含的内存视为一个单独的可用内存池。每个池都有自己的可用页列表、用于管理在用的LRU列表、统计信息和其他管理结构(包括序列化对列表的访问的锁)。内核将这些数据结构分配到由这些数据结构管理的node的内存中。Linux通过使本地CPU对node的内存请求有利于该node的页面池,从而最大化自己的内存访问和请求内存的任务的本地性。

随着新版本内核对Linux NUMA支持的改进,如Red Hat Enterprise Linux 5、6和7,节点交错(node interleaving)式不具优势,特别是在更大的系统配置上。在某些情况下,节点交错会导致显著的性能下降。当在系统firmware中启用节点交错时,内核不知道内存页相对于系统实际NUMA拓扑的位置。。结果,数据结构可以被分配到距离它们被大量使用的地方最远的页面上,从而导致次优的内核和应用程序性能。所以HPE不建议启用节点交错(node interleaving)。

怎么做?

当你进去BIOS之后,你还会看到一个option,Channel interleaving,要不要改呢?根据表Workload Profiles General Power Efficient Compute—Low Latency的列式,所有模式都应该是Enabled。千万不能改错了。

那什么是memory interleaving/channel interleaving呢?

好多文章被墙了,这里有一篇讲了high order/lower order,基本就是我们通常讲的little endian.:http://fourier.eng.hmc.edu/e85_old/lectures/memory/node2.html

一般来说,CPU更可能需要访问存储器以获得一组连续的字(程序中的连续指令段或数据结构的组件,例如数组), Lower Order arrangement的情况下memory interleaved会更优的,因为连续的字在不同的模块中可以同时提取。所以就不需要更改了。

文章内容可能有错,如果发现,欢迎指出。

参考内容:

1.https://www.kernel.org/doc/html/latest/vm/numa.html

2.Red Hat Linux NUMA Support for HP ProLiant Servers(https://support.hpe.com/hpsc/doc/public/display?docId=emr_na-c03261871)

3.Red Hat Enterprise Linux NUMA support for HPE ProLiant servers(https://h50146.www5.hpe.com/products/software/oe/linux/mainstream/support/whitepaper/pdfs/a00039147enw.pdf)

4.UEFI System Utilities User Guide for HPE ProLiant Gen10 Servers and HPE Synergy(https://support.hpe.com/hpsc/doc/public/display?docId=emr_na-a00016407ja_jp)

5.Linux NUMA support for HP ProLiant servers(https://h50146.www5.hpe.com/products/software/oe/linux/mainstream/support/whitepaper/pdfs/c03261871_2012.pdf)

6.https://blog.csdn.net/shaoyunzhe/article/details/53606584

7.UEFI System Utilities User Guide for HPE ProLiant Gen10 Servers and HPE Synergy(https://techlibrary.hpe.com/docs/iss/proliant_uefi/UEFI_Gen9_121417/s_enable_node_interleaving.html)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据工人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档