导读:本期聚焦于阿亮创作的《CDN节点频繁使用Swap怎么办?调整vm.swappiness优化内存管理》,敬请观看详情。一台负责边缘缓存的CDN节点在晚高峰时响应时间突然从20ms涨到300ms,查看监控发现物理内存只用了60%,Swap分区却占用了2GB,磁盘的si和so持续不为零。问题的根源不是内存不够,而是内核过度倾向于将匿名页换出到磁盘。通过调整vm.swappiness参数,可以改变内核对匿名页和文件页的回收倾向,让CDN缓存进程的堆内存尽量留在物理内存中,避免磁盘I/O等待拖垮整体吞吐。本文将拆解该参数的工作原理,说明CDN节点对Swap敏感的原因,并给出临时调整、持久化配置以及后续监控的完整步骤。

CDN节点在晚高峰出现响应延迟,排查时发现物理内存占用率只有65%,但Swap分区已经使用了2GB,磁盘的si和so字段持续不为零。运维人员第一反应通常是增加物理内存,但如果节点上还挂着大容量NVMe做缓存盘,磁盘I/O被Swap换页占用,整体缓存吞吐会明显下降。这个问题的关键往往不只在内存容量,还与内核的换出倾向有关,也就是vm.swappiness参数。

CDN节点频繁使用Swap怎么办?调整vm.swappiness优化内存管理

一、vm.swappiness 控制了什么

Linux内核在物理内存不足时,需要回收一部分内存页面。页面大致分为两类:一类是文件页,也就是从磁盘读取的文件缓存,例如CDN节点上缓存的静态资源、日志文件、Nginx读取的配置文件;另一类是匿名页,通常来自进程运行时的堆、栈以及动态分配的内存,比如Nginx worker进程的请求上下文、连接状态、缓存索引结构等。文件页回收的代价相对较低,因为内容本身在磁盘上有对应的原始文件,内核只需要丢弃页面并在下次访问时重新读取。匿名页没有对应的磁盘文件,回收时必须写入Swap分区,后续访问还要从Swap读回,这个过程被称为换入换出。

vm.swappiness是一个内核参数,取值范围是0到100,它决定了内存回收时内核倾向于回收文件页还是换出匿名页。默认值通常是60,这个数值意味着在某些内存压力下,内核会优先考虑换出匿名页。对于通用的桌面或数据库服务器,这种平衡也许可以接受,但对于CDN边缘节点来说,进程的匿名页大量承载着热数据和高频访问路径,一旦被换到磁盘上,响应速度会急剧下降。

可以通过下面的命令查看当前节点的vm.swappiness值,默认部署的Linux发行版大多返回60。

# 查看当前 vm.swappiness 值
cat /proc/sys/vm/swappiness

# 或者使用 sysctl 命令查看
sysctl vm.swappiness

二、为什么CDN节点对Swap尤其敏感

CDN节点的主要职责是快速返回缓存内容。一个请求进来后,Nginx或者Varnish需要根据URL、Host、Cookie等维度计算缓存键,然后在内存中的哈希表里查找是否有对应的缓存条目。如果缓存命中,直接从内存或磁盘缓存中取出内容返回。这个查找过程依赖大量常驻内存的索引结构,而这些结构通常以匿名页的形式存在。如果内核把这些匿名页换出到Swap,请求过来时就必须等待磁盘I/O把页面换回内存,这一来一回可能从几十微秒变成几毫秒甚至几十毫秒。

更重要的是,Swap换入换出不仅消耗时间,还会占用磁盘带宽。CDN节点上的磁盘经常同时承担缓存文件的读写,如果Swap频繁换页,磁盘的随机I/O压力会明显增加。原本可以支撑高吞吐的NVMe缓存盘,可能因为混杂了大量Swap I/O而出现响应延迟。很多线上事故都表现为磁盘利用率不高,但延迟抖动严重,查看vmstat后才发现si和so列持续大于零。

此外,Nginx采用多进程模型,每个worker进程都有自己独立的地址空间。一旦某个worker的堆内存被换出,该worker处理的所有连接都会受到影响。如果多个worker同时被换出,整个节点的可用性会迅速恶化。因此,CDN节点应当尽量避免匿名页被写入Swap,这也是调低vm.swappiness的核心目的。

三、调整 vm.swappiness 的完整流程

调整参数之前,建议先确认当前Swap分区的大小和使用情况。使用free -h可以看到总内存、已用内存以及Swap的占用情况。如果Swap使用量已经很高,调整参数后还需要主动释放一部分Swap,否则已换出的页面不会因为参数改变而自动回到内存中。可以通过swapoff -a再swapon -a来强制回收Swap,但生产环境执行此操作前必须评估风险,最好在低峰期操作,并确保物理内存足够容纳所有换出的页面。

临时调整非常简单,使用sysctl -w命令即可立即生效,但重启后会恢复默认值。

# 临时调整为 10,立即生效但重启后失效
sudo sysctl -w vm.swappiness=10

# 验证是否生效
cat /proc/sys/vm/swappiness

如果需要长期生效,可以写入/etc/sysctl.d/目录下的配置文件。文件名可以自定义,通常按数字前缀排序加载,这里使用99-swappiness.conf保证在系统默认配置之后加载,避免被覆盖。

# 创建持久化配置文件
printf 'vm.swappiness=10\n' | sudo tee /etc/sysctl.d/99-swappiness.conf

# 重新加载 sysctl 配置
sudo sysctl --system

# 查看最终生效值
sysctl vm.swappiness

关于取值,很多生产环境的CDN节点选择10或者1。数值越低,内核越不愿意换出匿名页。设置为0在新版内核中表示尽量禁止匿名页换出,但有些资料认为0在极端内存压力下仍可能触发换出,而1是更明确的保守换出策略。实际使用中10是相对稳妥的选择,既为系统保留了一定的匿名页回收能力,又能显著减少不必要的Swap活动。

四、验证效果与后续监控

调整完成后,需要通过监控手段确认Swap是否还在增长。vmstat 1可以每秒输出一次内存和Swap活动,其中si表示从Swap换入的页数,so表示换出到Swap的页数。正常运行时这两个值应该长时间保持为0,偶尔有少量换入可以接受,但如果持续大于零,说明参数调整没有达到预期效果。

# 每秒输出一次内存与 Swap 活动,si 和 so 列为换入换出页数
vmstat 1

# 查看 Swap 占用情况
free -h

# 查看某个进程的 Swap 使用量,将 1234 替换为目标 PID
grep VmSwap /proc/1234/status

除了全局监控,还可以针对Nginx或Varnish的worker进程查看各自的Swap占用。在/proc/进程ID/status文件中有一个VmSwap字段,记录了该进程被换出到Swap的内存大小。如果调整参数后,某些进程的VmSwap仍然持续增长,需要排查是否存在内存泄漏,或者进程本身的内存需求已经超出了物理内存容量。

对于使用cgroup v2的系统,还可以配合memory.swap.max来限制cgroup内进程的最大Swap使用量。例如,将CDN相关进程放入一个专门的cgroup,并设置memory.swap.max=0,可以完全禁止该cgroup内的进程使用Swap。这种方式比单纯调整vm.swappiness更加严格,适合对延迟极其敏感的边缘节点。

建议在监控系统中添加告警规则:当节点的si或so连续五分钟大于0,或者Swap使用量超过物理内存的5%时触发告警。这样可以在问题影响用户之前介入处理,避免CDN节点因为Swap抖动导致缓存命中率下降和响应时间恶化。

vm.swappiness内存管理CDN节点修改时间:2026-09-18 04:07:55

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0918/58668.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。