阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Linux内核页回收swappiness参数有着什么作用

77次阅读
没有评论

共计 3609 个字符,预计需要花费 10 分钟才能阅读完成。

这两天看微博上有人讨论 swappiness 相关问题,mysqlperformanceblog 上也有人说将 swappiness 设成 0 后 MySQL 被“意外”kill 掉,另外自己所在团队线上也遇到过类似问题,大家对这个参数的含义可能还不是很清楚,个人尝试写篇文章详细解释下这个参数。

本文主要尝试解释两个问题:
1. swappiness 的确切含义是什么,它对内核进行页回收机制的影响。
2. swappiness 设置成 0,为什么系统仍然可能会有 swap 发生。

一. 关于内存分配与页回收 (page reclaim)

page reclaim 发生的场景主要有两类,一个是 kswapd 后台线程进行的活动,另一个是 direct reclaim,即分配页时没有空闲内存满足,需要立即直接进行的页回收。大体上内存分配的流程会分为两部分,一部分是 fast path,另一部分是 slow path,通常内存使用非紧张情况下,都会在 fast path 就可以满足要求。并且 fast path 下的内存分配不会出现 dirty writeback 及 swap 等页回收引起的 IO 阻塞情况。

fast path 大体流程如下:
1. 如果系统挂载使用了 memory cgroup,则首先检查是否超过 cgroup 限额,如果超过则进行 direct reclaim,通过 do_try_to_free_pages 完成。如果没超过则进行 cgroup 的 charge 工作(charge 是通过两阶段提交完成的,这里不展开了)。
2. 从本地 prefered zone 内存节点查找空闲页,需要判断是否满足系统 watermark 及 dirty ratio 的要求,如果满足则从 buddy system 上摘取相应 page, 否则尝试对本地 prefered zone 进行页回收, 本次 fast path 下页回收只会回收 clean page,即不会考虑 dirty page 以及 mapped page,这样就不会产生任何 swap 及 writeback,即不会引起任何 blocking 的 IO 操作,如果这次回收仍然无法满足请求的内存页数目则进入 slow path

slow path 大体流程如下:
1. 首先唤醒 kswapd 进行 page reclaim 后台操作。
2. 重新尝试本地 prefered zone 进行分配内存,如果失败会根据请求的 GFP 相关参数决定是否尝试忽略 watermark, dirty ratio 以及本地节点分配等要求进行再次重试,这一步中如果分配页时有指定__GFP_NOFAIL 标记,则分配失败会一直等待重试。
3. 如果没有__GFP_NOFAIL 标记,则会需开始进行 page compact 及 page direct reclaim 操作,之后如果仍然没有可用内存,则进入 OOM 流程。

相关内容可以参阅内核代码__alloc_pages 函数的逻辑,另外无论 page reclaim 是由谁发起的,最终都会统一入口到 shrink_zone,即针对每个 zone 独立进行 reclaim 操作,最终会进入 shrink_lruvec 函数,进行每个 zone 相应 page lru 链表的扫描与回收操作。

二. 关于页回收的一些背景知识

页回收大体流程会先在每个 zone 上扫描相应的 page 链表,主要包括 inactive anon/active anon(匿名页链表) 以及 inactive file/active file 链表(file cache/ 映射页链表),一共四条链表,我们所有使用过的 page 在被回收前基本是保存在这四条链表中的某一条中的(还有一部分在 unevictable 链表中,忽略),根据其被引用的次数会决定其处于 active 还是 inactive 链表中,根据其类型决定处于 anon 还是 file 链表中。

页回收总体会扫描逐个内存节点的所有 zone,然后先扫描 active,将不频繁访问的页挪到 inactive 链表中,随后扫描 inactive 链表,会将其中被频繁引用的页重新挪回到 active 中,确认不频繁的页则最终被回收,如果是 file based 的页则根据是否 clean 进行释放或回写 (writeback,filecache 则直接释放),如果是 anon 则进行 swap,所以本文实际关心的是 swappiness 参数对 anon 链表扫描的影响。

另外还需要了解前面描述的四个链表原来是放在 zone 数据结构上的,后来引入了 mem_cgroup 则,重新定义了一组 mem_cgroup_per_zone/mem_cgroup_per_node 的数据结构,这四个链表同时定义在这组数据结构上,如果系统开启了 mem cgroup 则使用后者,否则用前者。

另外再重点说下 swap 只是 page reclaim 的一种处理措施,主要针对 anon page,我们最终来看下 swappiness 的确切含义

三. swappiness 对 page reclaim 的确切影响

page reclaim 逻辑中对前面所述四个链表进行扫描的逻辑在 vmscan.c 中的 get_scan_count 函数内,该函数大部分逻辑注释写得非常清楚,我们简单梳理下,主要关注 scan_balance 变量的取值:

1. 首先如果系统禁用了 swap 或者没有 swap 空间,则只扫描 file based 的链表,即不进行匿名页链表扫描
代码如下:

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

2. 如果当前进行的不是全局页回收(cgroup 资源限额引起的页回收),并且 swappiness 设为 0,则不进行匿名页链表扫描,这个是没得商量,这里 swappiness 值直接决定了是否有 swap 发生,设成 0 则肯定不会发生,另外需要注意,这种情况下需要设置的是 cgroup 配置文件 memory.swappiness,而不是全局的 sysctl vm.swappiness
代码如下:

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

3. 如果进行链表扫描前设置的 priority(这个值决定扫描多少分之一的链表元素) 为 0,且 swappiness 非 0,则可能会进行 swap
代码如下:

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

4. 如果是全局页回收,并且当前空闲内存和所有 file based 链表 page 数目的加和都小于系统的 high watermark,则必须进行匿名页回收,则必然会发生 swap, 可以看到这里 swappiness 的值如何设置是完全无关的,这也解释了为什么其为 0,系统也会进行 swap 的原因,另外最后我们会详细解释系统 page watermark 是如何计算的。
代码如下:

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

5. 如果系统 inactive file 链表比较充足,则不考虑进行匿名页的回收,即不进行 swap
代码如下:

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

6. 最后一种情况则要根据 swappiness 值与之前统计的 file 与 anon 哪个更有价值来综合决定 file 和 anon 链表扫描的比例,这时如果 swappiness 设置成 0,则也不会扫描 anon 链表,即不进行 swap, 代码比较多,不再贴出。

四. 系统内存 watermark 的计算

前面看到系统内存 watermark 对页回收机制是有决定影响的,其实在内存分配中也会频繁用到这个值,确切的说它有三个值,分别是 low,min 和 high, 根据分配页时来指定用哪个,如果系统空闲内存低于相应 watermark 则分配会失败,这也是进入 slow path 或者 wakeup kswapd 的依据。

实际这个值的计算是通过 sysctl 里的 vm.min_free_kbytes 来决定的,大体的计算公式如下:

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

即根据 min_free_kbytes 的值按照每个 zone 管理页面的比例算出 zone 的 min_watermark,然后再加 min 的 1 / 4 就是 low,加 1 / 2 就是 high 了

总结:

swappiness 的值是个参考值,是否会发生 swap 跟当前是哪种 page reclaim 及系统当前状态都有关系,所以设置了 swappiness= 0 并不代表一定没有 swap 发生,同时设为 0 也确实会可能发生 OOM。

个人仍然认为线上环境设置 swappiness= 0 是没有任何问题的。

文章来自微信公众号:运维帮

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-07-24发表,共计3609字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中