首页 > 代码库 > NUMA对MySQL InnoDB的性能影响
NUMA对MySQL InnoDB的性能影响
http://blog.jcole.us/2010/09/28/mysql-swap-insanity-and-the-numa-architecture/
NUMA架构的CPU下,一个CPU有多个核心,那么每个CPU成为一个NODE
关闭这个特性时
一个NODE 使用自己的本地内存,而尽量不去访问其他NODE的内存,除非本地内存满了
Linux 如何处理NUMA架构
1 把处理器分到节点(NODE),现代处理器一般是每个节点一个处理器,一个处理器上多个核
2 为每个节点连接每个处理器的本地内存模块
3 计算节点间的沟通成本(节点距离)
通过numactl --hardware 命令可以看到Linux如何识别NUMA架构层
available: 4 nodes (0-3)
node 0 cpus: 0 1 2 3 4 5 6 7 32 33 34 35 36 37 38 39
node 0 size: 65512 MB
node 0 free: 2146 MB
node 1 cpus: 8 9 10 11 12 13 14 15 40 41 42 43 44 45 46 47
node 1 size: 65536 MB
node 1 free: 96 MB
node 2 cpus: 16 17 18 19 20 21 22 23 48 49 50 51 52 53 54 55
node 2 size: 65536 MB
node 2 free: 32362 MB
node 3 cpus: 24 25 26 27 28 29 30 31 56 57 58 59 60 61 62 63
node 3 size: 65536 MB
node 3 free: 21805 MB
node distances:
node 0 1 2 3
0: 10 11 11 11
1: 11 10 11 11
2: 11 11 10 11
3: 11 11 11 10
内存是平均分配到每个节点的
# Linux 如何处理资源分配
每个进程和线程继承父亲的NUMA策略.这个策略可以基于每个线程修改.
策略定义了一个进程允许被哪个节点甚至那个核心调度.
每个线程最初配分派给最"适合"的节点运行.线程也可以在其他地方运行,但是调度器试图确保现场运行在最优节点
默认情况下,内存的分配被指派到特定的节点上,即这个线程"当前"运行的节点.
在UMA/SMP 架构下,内存是平等对待的,而在NUMA下,分配其他节点的内存意味着cache的延迟和性能的下降
内存一旦分配到一个节点上,就不会移动到另一个节点,不管系统的需求,它会永远呆在那个节点上.
任何进程的NUMA策略可以被修改,通过numactl作为程序的封装,也可以使用 libnuma 编写代码管理NUMA策略.
例如使用numactl作为程序的封装:
1 使用指定策略分配内存:
使用"当前"节点,--localalloc参数指定,这是默认的模式
优先使用一个节点,但也可以使用其他节点,--preferred=node参数
永远使用一个节点或一组节点, --membind=nodes
交叉,轮询所有节点 --interleaved=all 或者 --interleaved=nodes
2 程序运行节点的选择
指定节点(--cpunodebind=nodes) 或者 一个核心或一组核心 (--physcpubind=cpus)
NUMA 对 MySQL 和 InnoDB 的意义
对于InnoDB和大多数数据库服务器(如Oracle),他们在Linux上的工作方式是,巨大的单一进程,带有多线程.
在NUMA架构下,内存被分派到不同的节点上,当你分配了系统50%以上的内存给一个进程,这就不是一个节点内能完成的事情了.
当不同的查询同时运行时,每个处理器都无法优先地去访问一个特定查询需要内存
事实证明这是一个很重要的问题.通过/proc/pid/numa_maps可以看到mysqld分配的所有内存,你会发现一个有趣的现象
如果你查找anon=size的值,
这是其中一行的值
7ecf14000000 default anon=3584 dirty=3584 active=1024 N1=3584
7ecf14000000 虚拟内存地址
default NUMA 策略
anon=number 匿名页面的数量
dirty 脏页,被修改的页
通常分配给进程的页总是使用的,因此都是脏的,但是由于fork,进程会有很多copy-on-write的页面的映射,他们不是脏的
swapcache=number
active 这个列出现,表示多少页面出现在活动列表,同时意味着还有一些不活跃的页面,它们将要被swapper换页出去
N0 and N1 每个节点的页面
通过一个脚本,可以统计出所有内存的情况
perl /data0/script/numa-maps-summary.pl < /proc/4417/numa_maps
N0 : 392133 ( 1.50 GB)
N1 : 792466 ( 3.02 GB)
N2 : 531028 ( 2.03 GB)
N3 : 3743392 ( 14.28 GB)
active : 4314131 ( 16.46 GB)
anon : 5457149 ( 20.82 GB)
dirty : 5456665 ( 20.82 GB)
mapmax : 268 ( 0.00 GB)
mapped : 1930 ( 0.01 GB)
swapcache : 484 ( 0.00 GB)
读取/proc/pid/numa_maps的信息会阻塞进程
http://blog.wl0.org/2012/09/checking-procnuma_maps-can-be-dangerous-for-mysql-client-connections/
不但是mysql 还有mangodb
根据官方文档的解释,Linux, NUMA, MongoDB 这三者不是很和谐,如果当前硬件是 NUMA 的,可以把它给关了:
# numactl --interleave=all sudo -u mongodb mongod --port xxx --logappend --logpath yyy --dbpath zzz
(vm.overcommit_ratio = 100, vm.overcommit_memory = 2)
vm.zone_reclaim_mode 设置为 0。
系统给 NUMA node 分配内存,如果 NUMA node 已经满了,这时候,系统会为本地的 NUMA node 回收内存而不是将多出来的内存给 remote NUMA node,这样整体的性能会更好,但是在某些情况下,给 remote NUMA node 分配内存会比回收本地的 NUMA node 更好,这时候就需要将 zone_reclaim_mode 给关闭了
numactl --interleave all
NUMA对MySQL InnoDB的性能影响