NUMA的取舍与优化设置

NUMA的取舍与优化设置

2023年7月3日发(作者:)

NUMA的取舍与优化设置 在os层numa关闭时,打开bios层的numa会影响性能,QPS会下降15-30%; 在bios层⾯numa关闭时,⽆论os层⾯的numa是否打开,都不会影响性能。

安装numactl:

#yum install numactl -y #numastat 等同于 cat /sys/devices/system/node/node0/numastat ,在/sys/devices/system/node/⽂件夹中记录系统中的所有内存节点的相关详细信息。   #numactl --hardware 列举系统上的NUMA节点 #numactl --show 查看绑定信息

Redhat或者Centos系统中可以通过命令判断bios层是否开启numa # grep -i numa /var/log/dmesg 如果输出结果为: No NUMA configuration found

说明numa为disable,如果不是上⾯内容说明numa为enable,例如显⽰:NUMA: Using 30 for the hash shift. 可以通过lscpu命令查看机器的NUMA拓扑结构。当发现numa_miss数值⽐较⾼时,说明需要对分配策略进⾏调整。例如将指定进程关联绑定到指定的CPU上,从⽽提⾼内存命中率。--------------------------------------------- 现在的机器上都是有多个CPU和多个内存块的。以前我们都是将内存块看成是⼀⼤块内存,所有CPU到这个共享内存的访问消息是⼀样的。这就是之前普遍使⽤的SMP模型。但是随着处理器的增加,共享内存可能会导致内存访问冲突越来越厉害,且如果内存访问达到瓶颈的时候,性能就不能随之增加。NUMA(Non-Uniform Memory Access)就是这样的环境下引⼊的⼀个模型。⽐如⼀台机器是有2个处理器,有4个内存块。我们将1个处理器和两个内存块合起来,称为⼀个NUMA node,这样这个机器就会有两个NUMA node。在物理分布上,NUMA node的处理器和内存块的物理距离更⼩,因此访问也更快。⽐如这台机器会分左右两个处理器(cpu1, cpu2),在每个处理器两边放两个内存块(memory1.1, memory1.2, memory2.1,memory2.2),这样NUMA node1的cpu1访问memory1.1和memory1.2就⽐访问memory2.1和memory2.2更快。所以使⽤NUMA的模式如果能尽量保证本node内的CPU只访问本node内的内存块,那这样的效率就是最⾼的。在运⾏程序的时候使⽤numactl -m和-physcpubind就能制定将这个程序运⾏在哪个cpu和哪个memory中。 给了⼀个表格,当程序只使⽤⼀个node资源和使⽤多个node资源的⽐较表(差不多是38s与28s的差距)。所以限定程序在numa node中运⾏是有实际意义的。但是呢,话⼜说回来了,制定numa就⼀定好吗?--numa的陷阱。⽂章就说到了⼀个numa的陷阱的问题。现象是当你的服务器还有内存的时候,发现它已经在开始使⽤swap了,甚⾄已经导致机器出现停滞的现象。这个就有可能是由于numa的限制,如果⼀个进程限制它只能使⽤⾃⼰的numa节点的内存,那么当⾃⾝numa node内存使⽤光之后,就不会去使⽤其他numa node的内存了,会开始使⽤swap,甚⾄更糟的情况,机器没有设置swap的时候,可能会直接死机!所以你可以使⽤numactl --interleave=all来取消numa node的限制。

综上所述得出的结论就是,根据具体业务决定NUMA的使⽤。如果你的程序是会占⽤⼤规模内存的,你⼤多应该选择关闭numa node的限制(或从硬件关闭numa)。因为这个时候你的程序很有⼏率会碰到numa陷阱。另外,如果你的程序并不占⽤⼤内存,⽽是要求更快的程序运⾏时间。你⼤多应该选择限制只访问本numa node的⽅法来进⾏处理。---------------------------------------------------------------------内核参数overcommit_memory :它是 内存分配策略可选值:0、1、2。0:表⽰内核将检查是否有⾜够的可⽤内存供应⽤进程使⽤;如果有⾜够的可⽤内存,内存申请允许;否则,内存申请失败,并把错误返回给应⽤进程。1:表⽰内核允许分配所有的物理内存,⽽不管当前的内存状态如何。2:表⽰内核允许分配超过所有物理内存和交换空间总和的内存内核参数zone_reclaim_mode:可选值0、1a、当某个节点可⽤内存不⾜时:1、如果为0的话,那么系统会倾向于从其他节点分配内存2、如果为1的话,那么系统会倾向于从本地节点回收Cache内存多数时候b、Cache对性能很重要,所以0是⼀个更好的选择----------------------------------------------------------------------mongodb的NUMA问题mongodb⽇志显⽰如下:WARNING: You are running on a NUMA suggest launching mongod like this to avoid performance problems:numactl –interleave=all mongod [other options]解决⽅案,临时修改numa内存分配策略为 interleave=all (在所有node节点进⾏交织分配的策略):1.在原启动命令前⾯加numactl –interleave=all如# numactl --interleave=all ${MONGODB_HOME}/bin/mongod --config conf/2.修改内核参数echo 0 > /proc/sys/vm/zone_reclaim_mode ; echo "_reclaim_mode = 0" >> /etc/----------------------------------------------------------------------⼀、NUMA和SMPNUMA和SMP是两种CPU相关的硬件架构。在SMP架构⾥⾯,所有的CPU争⽤⼀个总线来访问所有内存,优点是资源共享,⽽缺点是总线争⽤激烈。随着PC服务器上的CPU数量变多(不仅仅是CPU核数),总线争⽤的弊端慢慢越来越明显,于是Intel在Nehalem CPU上推出了NUMA架构,⽽AMD也推出了基于相同架构的Opteron CPU。NUMA最⼤的特点是引⼊了node和distance的概念。对于CPU和内存这两种最宝贵的硬件资源,NUMA⽤近乎严格的⽅式划分了所属的资源组(node),⽽每个资源组内的CPU和内存是⼏乎相等。资源组的数量取决于物理CPU的个数(现有的PC server⼤多数有两个物理CPU,每个CPU有4个核);distance这个概念是⽤来定义各个node之间调⽤资源的开销,为资源调度优化算法提供数据⽀持。⼆、NUMA相关的策略1、每个进程(或线程)都会从⽗进程继承NUMA策略,并分配有⼀个优先node。如果NUMA策略允许的话,进程可以调⽤其他node上的资源。2、NUMA的CPU分配策略有cpunodebind、physcpubind。cpunodebind规定进程运⾏在某⼏个node之上,⽽physcpubind可以更加精细地规定运⾏在哪些核上。3、NUMA的内存分配策略有localalloc、preferred、membind、interleave。localalloc规定进程从当前node上请求分配内存;⽽preferred⽐较宽松地指定了⼀个推荐的node来获取内存,如果被推荐的node上没有⾜够内存,进程可以尝试别的node。membind可以指定若⼲个node,进程只能从这些指定的node上请求分配内存。interleave规定进程从指定的若⼲个node上以RR(Round Robin 轮询调度)算法交织地请求分配内存。

因为NUMA默认的内存分配策略是优先在进程所在CPU的本地内存中分配,会导致CPU节点之间内存分配不均衡,当某个CPU节点的内存不⾜时,会导致swap产⽣,⽽不是从远程节点分配内存。这就是所谓的swap insanity 现象。MySQL采⽤了线程模式,对于NUMA特性的⽀持并不好,如果单机只运⾏⼀个MySQL实例,我们可以选择关闭NUMA,关闭的⽅法有三种:1.硬件层,在BIOS中设置关闭内核,启动时设置numa=off;3.可以⽤numactl命令将内存分配策略修改为interleave(交叉)。如果单机运⾏多个MySQL实例,我们可以将MySQL绑定在不同的CPU节点上,并且采⽤绑定的内存分配策略,强制在本节点内分配内存,这样既可以充分利⽤硬件的NUMA特性,⼜避免了单实例MySQL对多核CPU利⽤率不⾼的问题三、NUMA和swap的关系可能⼤家已经发现了,NUMA的内存分配策略对于进程(或线程)之间来说,并不是公平的。在现有的Redhat 中,localalloc是默认的NUMA内存分配策略,这个配置选项导致资源独占程序很容易将某个node的内存⽤尽。⽽当某个node的内存耗尽时,Linux⼜刚好将这个node分配给了某个需要消耗⼤量内存的进程(或线程),swap就妥妥地产⽣了。尽管此时还有很多page cache可以释放,甚⾄还有很多的free内存。四、解决swap问题虽然NUMA的原理相对复杂,实际上解决swap却很简单:只要在启动MySQL之前使⽤numactl –interleave来修改NUMA策略即可。值得注意的是,numactl这个命令不仅仅可以调整NUMA策略,也可以⽤来查看当前各个node的资源使⽤情况,是⼀个很值得研究的命令。

⼀、CPU  ⾸先从CPU说起。  你仔细检查的话,有些服务器上会有的⼀个有趣的现象:你cat /proc/cpuinfo时,会发现CPU的频率竟然跟它标称的频率不⼀样:  #cat /proc/cpuinfo  processor : 5  model name : Intel(R) Xeon(R) CPU E5-2620 0 @2.00GHz  cpu MHz : 1200.000  这个是Intel E5-2620的CPU,他是2.00G * 24的CPU,但是,我们发现第5颗CPU的频率为1.2G。  这是什么原因呢?  这些其实都源于CPU最新的技术:节能模式。操作系统和CPU硬件配合,系统不繁忙的时候,为了节约电能和降低温度,它会将CPU降频。这对环保⼈⼠和抵制地球变暖来说是⼀个福⾳,但是对MySQL来说,可能是⼀个灾难。  为了保证MySQL能够充分利⽤CPU的资源,建议设置CPU为最⼤性能模式。这个设置可以在BIOS和操作系统中设置,当然,在BIOS中设置该选项更好,更彻底。由于各种BIOS类型的区别,设置为CPU为最⼤性能模式千差万别,我们这⾥就不具体展⽰怎么设置了。  然后我们看看内存⽅⾯,我们有哪些可以优化的。  i) 我们先看看numa  ⾮⼀致存储访问结构 (NUMA : Non-Uniform Memory Access) 也是最新的内存管理技术。它和对称多处理器结构 (SMP : Symmetric Multi-Processor)是对应的。简单的队别如下:  如图所⽰,详细的NUMA信息我们这⾥不介绍了。但是我们可以直观的看到:SMP访问内存的都是代价都是⼀样的;但是在NUMA架构下,本地内存的访问和⾮ 本地内存的访问代价是不⼀样的。对应的根据这个特性,操作系统上,我们可以设置进程的内存分配⽅式。⽬前⽀持的⽅式包括:  --interleave=nodes  --membind=nodes  --cpunodebind=nodes  --physcpubind=cpus  --localalloc  --preferred=node  简⽽⾔之,就是说,你可以指定内存在本地分配,在某⼏个CPU节点分配或者轮询分配。除⾮ 是设置为--interleave=nodes轮询分配⽅式,即内存可以在任意NUMA节点上分配这种⽅式以外。其他的⽅式就算其他NUMA节点上还有内 存剩余,Linux也不会把剩余的内存分配给这个进程,⽽是采⽤SWAP的⽅式来获得内存。有经验的系统管理员或者DBA都知道SWAP导致的数据库性能 下降有多么坑爹。  所以最简单的⽅法,还是关闭掉这个特性。  关闭特性的⽅法,分别有:可以从BIOS,操作系统,启动进程时临时关闭这个特性。  a) 由于各种BIOS类型的区别,如何关闭NUMA千差万别,我们这⾥就不具体展⽰怎么设置了。  b) 在操作系统中关闭,可以直接在/etc/的kernel⾏最后添加numa=off,如下所⽰:  kernel /6.x86_64 ro root=/dev/mapper/VolGroup-root rd_NO_LUKS LANG=en_-8 rd_LVM_LV=VolGroup/root rd_NO_MDquiet SYSFONT=latarcyrheb-sun16 rhgb crashkernel=auto rd_LVM_LV=VolGroup/swap rhgb crashkernel=auto quiet KEYBOARDTYPE=pc KEYTABLE=usrd_NO_DM numa=off  另外可以设置 _reclaim_mode=0尽量回收内存。  c) 启动MySQL的时候,关闭NUMA特性:  numactl --interleave=all mysqld  当然,最好的⽅式是在BIOS中关闭。  ii) 我们再看看ness。  ness是操作系统控制物理内存交换出去的策略。它允许的值是⼀个百分⽐的值,最⼩为0,最⼤运⾏100,该值默认为60。ness设置为0表⽰尽量少swap,100表⽰尽量将inactive的内存页交换出去。  具体的说:当内存基本⽤满的时候,系统会根据这个参数来判断是把内存中很少⽤到的inactive 内存交换出去,还是释放数据的cache。cache中缓存着从磁盘读出来的数据,根据程序的局部性原理,这些数据有可能在接下来⼜要被读 取;inactive 内存顾名思义,就是那些被应⽤程序映射着,但是 长时间 不⽤的内存。  我们可以利⽤vmstat看到inactive的内存的数量:  #vmstat -an 1  procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----  r b swpd free inact active si so bi bo in cs us sy id wa st  1 0 0 27522384 326928 1704644 0 0 0 153 11 10 0 0 100 0 0  0 0 0 27523300 326936 1704164 0 0 0 74 784 590 0 0 100 0 0  0 0 0 27523656 326936 1704692 0 0 8 8 439 1686 0 0 100 0 0  0 0 0 27524300 326916 1703412 0 0 4 52 198 262 0 0 100 0 0  通过/proc/meminfo 你可以看到更详细的信息:  #cat /proc/meminfo | grep -i inact  Inactive: 326972 kB  Inactive(anon): 248 kB  Inactive(file): 326724 kB  这⾥我们对不活跃inactive内存进⼀步深⼊讨论。 Linux中,内存可能处于三种状态:free,active和inactive。众所周知,Linux Kernel在内部维护了很多LRU列表⽤来管理内存,⽐如LRU_INACTIVE_ANON, LRU_ACTIVE_ANON, LRU_INACTIVE_FILE , LRU_ACTIVE_FILE, LRU_UNEVICTABLE。其中LRU_INACTIVE_ANON, LRU_ACTIVE_ANON⽤来管理匿名页,LRU_INACTIVE_FILE , LRU_ACTIVE_FILE⽤来管理page caches页缓存。系统内核会根据内存页的访问情况,不定时的将活跃active内存被移到inactive列表中,这些inactive的内存可以被 交换到swap中去。  ⼀般来说,MySQL,特别是InnoDB管理内存缓存,它占⽤的内存⽐较多,不经常访问的内存也会不少,这些内存如果被Linux错误的交换出去了,将浪费很多CPU和IO资源。 InnoDB⾃⼰管理缓存,cache的⽂件数据来说占⽤了内存,对InnoDB⼏乎没有任何好处。  所以,我们在MySQL的服务器上最好设置ness=1或0

发布者:admin,转转请注明出处:http://www.yc00.com/news/1688329078a121059.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信