温馨提示×

linux缓存为何失效

小樊
43
2026-10-03 14:42:54
栏目: 智能运维

在 Linux 系统中,“缓存失效”通常指页缓存(page cache)/ 目录项缓存(dentry cache)/ inode 缓存未能命中,或系统主动回收缓存,导致原本应从内存读取的数据被迫访问磁盘,性能下降。下面按常见原因 → 原理 → 排查/解决来梳理。


一、最常见的几类原因

1. 内存不足,系统主动回收缓存(最常见)

Linux 设计原则:空闲内存 = 浪费内存,所以会尽量用内存做缓存。
但当 可用内存不足 时,内核会通过 kswapd 回收 page cache。

表现:

  • free -h 中 available 很小
  • cache/buffer 突然下降
  • 磁盘 IO 明显上升

查看:

free -h
cat /proc/meminfo | egrep 'MemAvailable|Buffers|Cached'

解决:

  • 增加内存
  • 限制某些进程内存(cgroup / systemd)
  • 优化大文件读取方式(见后文)

2. 文件被修改或删除(缓存自动失效)

Linux 缓存是与文件内容强一致的:

  • 文件被写 → 对应 page cache 标记为脏 / 失效
  • 文件被删除 → inode/dentry 缓存释放
  • truncate / fallocate 也会失效

正常现象,不属于 bug。


3. 直接 IO(绕过缓存)

以下情况不会走 page cache:

  • O_DIRECT 打开文件
  • 数据库常用(MySQL、PostgreSQL)
  • 某些备份工具

验证:

strace -e trace=open,openat mysql ...

解决:

  • 如果是性能问题,考虑混合 IO 策略
  • 不要误以为“缓存没生效”

4. 文件过大,缓存被挤出

Linux 不会无限缓存:

  • 大文件顺序读
  • 内存被其他进程占用
  • 老缓存被 LRU 淘汰

现象:

  • 第一次读快,第二次反而慢
  • cache 增长但不持久

优化:

# 减少 swap 倾向
sysctl vm.swappiness=10

# 保护文件缓存
sysctl vm.vfs_cache_pressure=50

5. 频繁 stat / ls(dentry & inode 缓存失效)

以下操作会频繁刷新元数据缓存:

  • ls -l 大量文件
  • 高并发小文件
  • NFS / 网络文件系统

查看:

slabtop
cat /proc/slabinfo | grep dentry

6. 手动清理缓存(人为失效)

常见“误操作”:

echo 3 > /proc/sys/vm/drop_caches

这会立即清空:

  • page cache
  • dentry cache
  • inode cache

7. NUMA / 容器 / cgroup 限制

在以下环境中缓存“看起来失效”:

  • 容器内存限制过小
  • NUMA 节点内存不均
  • cgroup memory limit 触发回收

查看:

numactl --hardware
cat /sys/fs/cgroup/memory/memory.stat

二、如何判断“缓存是否真的失效”

1. 看缓存命中率

sar -B 1

关注:

  • cache 使用量
  • pgpgin / pgpgout
  • fault / majflt(主要缺页 = 缓存未命中)

2. 看是否 major fault

ps -o min_flt,maj_flt,cmd -p <pid>
  • maj_flt 高 = 缓存没用上

3. 用 fincore 看文件是否在缓存中

vmtouch file
# 或
fincore file

三、典型误区

❌ “Linux 缓存不会丢”
✅ 会丢,且应该丢

❌ “free 变少就是内存泄漏”
✅ 很可能只是 cache 在正常工作

❌ “drop_caches 能提升性能”
✅ 通常反而更慢


四、一句话总结

Linux 缓存“失效”大多不是 bug,而是内存压力、IO 模式、或配置导致缓存被回收或未使用。

如果你能补充:

  • 是什么场景(数据库 / 文件服务 / 容器)
  • 具体现象(命令、日志、IO 图)
  • 内核版本

我可以给你更精准的排查路径。

0 踩