swappiness=1在生产数据库服务器上成标配,因默认值60会过早换出匿名页引发毫秒级卡顿;设为1仅OOM时启用swap,兼顾安全与性能。
swappiness=1 在生产数据库服务器上几乎成了标配因为默认值 swappiness=60 会让内核在物理内存还有大量空闲时就急着把匿名页(如堆内存)换出到 swap,这对延迟敏感的数据库(PostgreSQL、MySQL)是灾难性的——一次 swapin 可能导致几百毫秒的卡顿。设为 1 并非禁用 swap,而是只在真正濒临 OOM 时才启用,既保留了安全垫,又避免了无谓抖动。
实操建议:
sudo sysctl vm.swappiness=1
/etc/sysctl.conf 中追加 vm.swappiness=1,再运行 sysctl -p
cat /proc/sys/vm/swappiness,不是看 sysctl vm.swappiness 的输出(可能缓存)vm.vfs_cache_pressure 调高还是调低?看你的 workload 类型这个参数控制内核回收 dentry 和 inode 缓存的积极程度。默认值 100 对通用场景合理,但对大量小文件读写的业务(如 Git 仓库服务、CI/CD 构建节点),缓存压力过大会频繁丢弃路径缓存,导致 open()、stat() 系统调用变慢。
实操建议:
50~80,保留更多 dentry/inode,减少路径查找开销120,避免缓存长期霸占内存0:内核不会完全不回收,且会引发其他异常行为(如 slabinfo 统计失真)grep -i "dentry\|inode" /proc/meminfo,结合 slabtop -o 看 dentry 和 inode_cache 占比echo 1 > /proc/sys/vm/drop_caches 在生产环境基本没用这条命令只能释放 pagecache、dentries 和 inodes,但无法释放 slab 分配器管理的内核对象(如 socket buffers、ext4 inode)、用户态进程堆内存、或被 mlock()
锁住的页。真正吃掉内存的往往是 slab 或应用自身泄漏,清 cache 只是“擦黑板”,不解决根本问题。
实操建议:
free -h 显示可用内存上升,不代表系统更健康Slab 占用持续增长(cat /proc/meminfo | grep Slab),优先查 slabtop -o 找 top 消耗者,比如 kmalloc-192 或 ext4_inode_cache
/proc/vmstat 中的 pgmajfault(缺页中断)、pgpgin/pgpgout(IO 换入换出量),比看 free 更可靠drop_caches 的脚本在生产环境属于危险操作,应禁止vm.overcommit_memory=1
这些应用启动时会预分配大量虚拟内存(如 Redis 的 maxmemory + 预留空间),但实际物理页按需分配。默认 overcommit_memory=0(启发式检查)会在进程 malloc() 超过系统剩余内存时直接失败,导致启动报 Cannot allocate memory,哪怕物理内存明明够用。
实操建议:
1 表示“永远允许 overcommit”,依赖 OOM killer 在真正爆内存时介入,这是最稳妥的选择2 并配 vm.overcommit_ratio:该模式下内核按硬公式计算可用内存(Swap + RAM * ratio/100),极易误判,尤其在 swap 关闭时直接归零malloc() 行为在进程启动时确定)cat /proc/sys/vm/overcommit_memory,同时检查 /proc/sys/vm/overcommit_ratio 是否仍为默认 50(设为 1 时该值无效)内存调优不是调参比赛,每个改动都要对应到具体 workload 的行为特征。最常被忽略的是:没关掉 transparent hugepage(/sys/kernel/mm/transparent_hugepage/enabled),它在某些 OLTP 场景下反而增加锁竞争和内存碎片。
# mysql
# postgresql
# 数据库
# 设为
# 默认值
# 换出
# 调高
# 标配
# 的是
# 按需分配
# 这是
# 器上
# elasticsearch
# 对象
# 堆
# linux
# redis
# git
# node
# go
# docker
# app
# 虚拟内存
# 为什么
# red
# echo
# 成了