hhajhh 发表于 2018-9-28 14:00:12

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>  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>  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>  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>  node 3 free: 21805 MB
  node distances:
  node   0   1   2   3
  0:10111111
  1:11101111
  2:11111011
  3:11111110
  内存是平均分配到每个节点的
  # 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

页: [1]
查看完整版本: NUMA对MySQL InnoDB的性能影响