23

为什么 Percona MySQL 开启 NUMA 选项后启动很慢

 4 years ago
source link: https://blog.arstercz.com/percona-mysql-start-slowly/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Written by arstercz


on July 13, 2020

为什么 Percona MySQL 开启 NUMA 选项后启动很慢

最近在使用新版本 Percona MySQL 的时候, 发现启动巨慢, 且启动时间随 innodb_buffer_pool_size 的大小成正比, 配置的 innodb_buffer_pool_size 值越大, 启动时间就越长, 所耗时间约为 T = innodb_buffer_pool_size(GB), 如下所示, 我们将 innodb_buffer_pool_size 配置的足够大, 就会发现实例启动耗时约 440s:

Jul  7 12:00:44 mysqld-3301[95109]: InnoDB: Initializing buffer pool, total size = 432G, instances = 24, chunk size = 256M
Jul  7 12:00:44 mysqld-3301[95109]: InnoDB: Setting NUMA memory policy to MPOL_INTERLEAVE
Jul  7 12:08:04 mysqld-3301[95109]: InnoDB: Setting NUMA memory policy to MPOL_DEFAULT
Jul  7 12:08:04 mysqld-3301[95109]: InnoDB: Completed initialization of buffer pool

可以看到消耗的时间主要在设置 NUMA 策略这步:

InnoDB: Setting NUMA memory policy to MPOL_INTERLEAVE

为什么要修改 NUMA 策略?

目前主流的服务器基本都是 NUMA 架构, 比起过去的 SMP 架构, NUMA 在 CPU 和内存利用率方面都有很大的提升. 不过 NUMA 架构对内存占用较多的应用(比如数据库等)存在一些性能方面的影响, 比较知名的有 MySQL swap insanity, 简单概括此问题即是 当你把主机大部分内存分配给InnoDB时,你会发现明明操作系统还有很多内存,但是却有很多内存被交换到了 SWAP 分区.

为什么会发生这样的问题? 主要的原因在于 MySQL 使用的内存超过了 NUMA 架构中单颗 CPU 对应的内存, 如下所示:

# numactl -H
available: 2 nodes (0-1)
node 0 cpus: 0 2 4 6 8 10
node 0 size: 32722 MB
node 0 free: 24803 MB
node 1 cpus: 1 3 5 7 9 11
node 1 size: 32768 MB
node 1 free: 28378 MB

每颗 CPU node 对应一半的内存(32G). 如果 MySQL 的内存超过 32G 就会产生上述的 swap insanity 问题. 更多描述可以参考以前的文章 MySQL numa交叉模式启动说明.

避免产生此类问题的方式目前主要就是修改 MySQL 的占用内存的策略, 保证可以使用每颗 CPU 对应的内存. MySQL 对 NUMA 的支持主要经过了以下阶段:

 numactl(命令行)  ->  numa_interleave(mysqld_safe 脚本) -> innodb_numa_interleave(mysqld 选项)

新版本的选项 innodb_numa_interleave 即可设置 MySQL 在启动的时候将 NUMA 内存策略从默认的 MPOL_DEFAULT 策略修改为 MPOL_INTERLEAVE 交互模式, 更多策略见 numa_memory_policy. 通过 INTERLEAVE 策略完成内存分配后, MySQL 又会将策略修改回默认的 DEFAULT 策略, 如下官方说明:

 Enables the NUMA interleave memory policy for allocation of the InnoDB buffer pool. 
 When innodb_numa_interleave is enabled, the NUMA memory policy is set to MPOL_INTERLEAVE 
 or the mysqld process. After the InnoDB buffer pool is allocated, the NUMA memory policy
 is set back to MPOL_DEFAULT. 

为什么启动很慢?

percona-PS-3967 的问题中, 自从 Oracle 官方引入 innodb_numa_interleave 功能后, Percona 版本之前的 NUMA 策略并没有生效, 为了解决这个问题, Percona 从以下版本开始在启用 NUMA INTERLEAVE 策略的时候一并通过 mmapMAP_POPULATE 标记预先分配 innodb_buffer_pool_size 指定的内存:

主版本 生效版本 5.6 >= 5.6.40-83.2 5.7 >= 5.7.22-22

这意味着 MySQL 在启动的时候就会预先占用 innodb_buffer_pool_size 指定的大小的内存, 指定的越大, 分配的时间就会越长, 如下所示:

Feature reverted from the upstream implementation back to the one ported from Percona Server 5.6, 
in which innodb_numa_interleave variable not only enables NUMA memory interleaving at InnoDB buffer
pool allocation, but allocates buffer pool with MAP_POPULATE, forcing interleaved allocation at 
the buffer pool initialization time.

再回到我们最开始的问题, 分配的 innodb_buffer_pool_size 为 432G, 启动时间约为 440s, mmap 平均每秒分配约 1G 左右的内存.

如何避免启动慢的问题?

实际上我们很少对数据库进行重启操作, 即便启动很慢, 影响也是很小. 不过如果想加快启动速度, 可以试着从以下几方面着手:

1. 降低 innodb_buffer_pool_size

尽量不要将此参数设置的过大, 如果数据很多能拆库尽量拆库.

2. 关闭 innodb_numa_interleave

如果实例使用的内存远小于单颗 cpu 对应的内存, 可以考虑关闭 numa 策略. 很多云主机实例仅一颗 CPU node, 无法开启 numa 的平衡策略(kernel.numa_balancing), 这种情况下就无需开启 innodb_numa_interleave 选项.

3. 保存 buffer pool

参考以下配置, 通过保存 buffer pool 状态加快启动过程, 同时也节省了不少数据预热的时间:

innodb_buffer_pool_load_at_startup = 1
innodb_buffer_pool_dump_at_shutdown = 1
innodb_buffer_pool_dump_pct = 60

更多见: Saving and Restoring the Buffer Pool State

4. 使用低版本 MySQL

如上所述的版本变更, 我们可以使用较低的版本, 不过可能出现 PS-3967 不生效的问题. 从笔者的使用经验来看, 可以参考以下版本:

percona mysql 5.6.38
percona mysql 5.7.19

5. 开启 large-page

可以考虑将共享缓存分配给 innodb buffer pool, MySQL 指定 large page 功能后, 就不需要通过 mmap 预分配指定的 innodb_buffer_pool_size 大小的缓存. 这种方式的启动时间和使用低版本的 MySQL 等同. 开启 large-page 的过程可参考: configuring-huge-page-for-MySQL, large-page-support.

a-brief-update-on-numa-and-mysql
5.6-innodb_numa_support
5.7-innodb_numa_support
percona_PS-3967
taobao-2015-07-05
numa_memory_policy


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK