共计 1488 个字符,预计需要花费 4 分钟才能阅读完成。
【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`
: