非对称存储访问结构(NUMA,NonUniform Memory Access)是最新的内存管理技术,是对多处理器结构(SMP,Symmetric MultiProcessor)改进。随着CPU核心数量和频率的不断提升,SMP下所有CPUCore都通过同一个内存控制器访问内存,性能瓶颈越来越严重。所以最新的多处理机服务器把内存控制拆分,由不同的CPU管理自己的内存地址。
NUMA的结构如图:
NUMA的特点:内存直接绑定在CPU上,CPU只有访问自身管理的内存物理地址时,才会有较短的响应时间;而访问其他CPU 管理的内存地址上的数据,就需要通过InterConnect通道访问,响应时间就会增加。
NUMA的策略:(可选其一) 1.默认(default):内存分配给正在执行进程的CPU。 3.交叉(interleave):在多个CPU上交织分配。 3.绑定(bind):绑定进程和内存到指定节点。 4.优先(preferred):优先在指定节点分配,失败再换节点。
NUMA在默认在本地CPU上分配内存,会导致CPU节点之间内存分配不均衡,当某个CPU节点的内存不足会使用Swap而不是直接从远程节点分配内存。经常内存还有耗尽,Mysql就已经使用Swap照成抖动,这就是"Swap Insanity"。因为Mysql的线程模型对NUMA支持不好,所以微信支付DB一般不使用NUMA。这时通过内核中设置numa=off或者numactl --interleave=all来关闭这个特性。
微信红包新架构需要启用单机多实例,为了性能最佳。决定使用CPU绑定策略,绑定CPU和内存分配,强制本地CPU分配内存。利用NUMA特性改进MySQL的多核利用率和竞争,实现性能最佳和影响隔离。
NUMACTL命令说明: --interleave=nodes :在指定节点上交织分配。 --membind=nodes :在指定节点上分配内存。 --cpunodebind=nodes :绑定到指定CPU节点。 --physcpubind=cpus :绑定到指定CPU核心。 --localalloc :强制在本地节点分配内存。 --preferred=node : 优先在指定节点分配内存。 这里的节点包含多个CPU核心,以我们的Z3为例。Z3有2颗CPU,每颗CPU有12核。这样就是2个节点,每个节点12核心。内存就是绑定在具体的物理CPU上。
我的测试开始走入一个误区,反复测试都发现绑定后性能下降;一直没有得到本地绑定的提升;恢复interleave时性能更好。初步测试结果(本次测试结果都是基于MySQLSlap工具在1000并发,重复50次下得到):
concurrency=1000 iterations=50 | |
---|---|
--interleave=all | 1.570 |
--cpunodebind=0 --localalloc | 2.335 |
--cpunodebind=0 --prefered=0 | 2.339 |
--preferred=1 | 1.583 |
--cpunodebind=0 --membind=0 | 2.338 |
多次测试结果稳定,BIND后性能大幅下降。而Preferred略微变慢。差距不大。 检查TOP,所有线程都在绑定的核心上运行。检查NUMASTAT,没有跨节点内存分配。
NUMA工作正常。然后,呃,最后到第二天才想到。。。单实例测试,可用CPU核心和内存减半,性能不下降才不正常。ORZ.... 准备2个实例,绑定到不同核心,多实例测试开始:
MySQL1(bind 0) | MySQL2(bind 1) | |
---|---|---|
--cpunodebind=0 --localalloc | 2.572 | 2.656 |
--interleave=all | 2.930 | 2.907 |
多实例下,NUMA的Bind模式效果很明显,绑定CPU和内存后有10%的提升。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。