[SWAP 产生原理]
先从 swap 产生的原理来分析, 由于 Linux 内存管理比较复杂, 下面以问答的方式列了一些重要的点, 方便大家理解:
1,swap 是如何产生的
swap 指的是一个交换分区或文件, 主要是在内存使用存在压力时, 触发内存回收, 这时可能会将部分内存的数据交换到 swap 空间.
2, 内存回收的机制
- <1>
- Linux 内核使用 cache 对部分文件进行缓存, 提升文件读写效率. 所以 引入了 kswapd 进程进行周期性检查, 保证剩余内存空间.
- <2>
- 当内存分配没有足够的空间时, 直接内存回收.
3, 内存回收如何实现
这部分实现非常复杂, 简单来说, 内存回收操作主要针对内存的文件页和匿名页, 这些页都通过 LRU 链表来管理.
其中 anon 的匿名页内存主要回收手段是 swap, 文件页释放方式是写回和清空.
4, 讲几个重要的概念
- <1>
- 内存节点 node, 在 NUMA 的情况下, CPU 访问不同位置的内存, 会有本地内存和远端内存之分, 这两个就是不同的节点.
- <2>
- 内存分区 zone,Linux 对内存节点做了进一步划分, 将一个节点划分为不同的区. 内存管理的逻辑以 zone 为单位.
- <3>
- 内存水位标记, 分为 high,low,min
通过下图可以比较直观的了解
5, 内存回收行为
- <1>
- 当系统剩余内存低于 low 时, kswapd 开始起作用进行内存回收, 直到内存达到 high 水位.
- <2>
- 当剩余内存达到 min 时就会触发直接回收.
- <3>
- 当触发全局回收, 并且 file+free
- <=high 时, 一定会进行针对匿名页的 swap.
下面举例:
在数据库做全备份时 cache 大量使用, 剩余可用空间不足, 触发内存回收,
上图是 / proc/zoneinfo 的部分内容, 可以看到满足了 file+free<=high 的条件, 同一时间触发了 swap, 将内存匿名页的数据写入交换区
有大量的文件页 cache, 为什么会出现 file+free<=high 的情况, 分析下来全备文件缓存时, node 0 的 nr_inactive_file 很低, 大部分非活动的文件页都分布在 node 1 上, 是由于开启 NUMA 导致的.
[关闭 NUMA 的方案]
1, 在 mysqld_safe 脚本中加上 "numactl -interleave all" 来启动 mysqld
2, Linux Kernel 启动参数中加上 numa=off, 需要重启服务器
3, 在 BIOS 层面关闭 NUMA
4, MySQL 5.6.27/5.7.9 开始引用 innodb_numa_interleave 选项
对于 2,3,4 关闭 NUMA 的方案比较简单, 不做详细描述, 下面重点描述下 1 方案
[开启 numa interleave 访问的步骤]
1, yum install numactl -y
2, 修改 / usr/bin/mysqld_safe 文件
cmd="`mysqld_ld_preload_text`$NOHUP_NICENESS" 下新增一条脚本
cmd="/usr/bin/numactl --interleave all $cmd"
- 3,service MySQL stop
- 4,# 写入硬盘, 防止数据丢失
- sync;sync;sync
- 5,# 延迟 10 秒
- sleep 10
- 6,# 清理 pagecache,dentries 和 inodes
- sysctl -q -w vm.drop_caches=3
- 7,service MySQL start
8, 验证 numactl -interleave all 是否生效, 可以通过下面命令, interleave_hit 是采用 interleave 策略从该节点分配的次数, 没有启动 interleave 策略的服务器, 这个值会很低
numastat -mn -p `pidof mysqld`
来源: http://www.linuxidc.com/Linux/2018-10/154976.htm