问题:
proxy_temp_path /www/server/nginx/proxy_temp_dir;
proxy_cache_path /www/server/nginx/proxy_cache_dir levels=1:2 keys_zone=cache_one:50m inactive=7d max_size=500g use_temp_path=off; # 客户端请求体的缓冲区大小
proxy_connect_timeout 180;
proxy_read_timeout 180;
proxy_send_timeout 180;
proxy_buffer_size 256k; # 初始缓冲区大小
proxy_buffers 8 256k; # 缓冲区数量和大小
proxy_busy_buffers_size 256k; # 保留在内存中的最大数据量
proxy_temp_file_write_size 1m; # 写入临时文件的大小
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404; proxy_cache cache_one;
以上是我的反向代理配置文件,为什么缓存还是超标了。三个区都超过了限制容量
分析 Nginx 代理缓存超标问题
您的 Nginx 代理缓存配置虽然设置了 max_size
参数,但缓存仍然超标,可能有以下几个原因:
可能的原因
- 缓存清理机制不活跃:
- Nginx 的缓存清理是惰性的,只有在缓存空间不足或达到
inactive
时间时才会清理 - 如果流量持续很高,可能清理速度跟不上新增缓存的速度
- Nginx 的缓存清理是惰性的,只有在缓存空间不足或达到
max_size
是软限制:- Nginx 的
max_size
不是硬性限制,缓存可能会暂时超过这个值 - 系统会在后台逐步清理旧缓存以达到限制
- Nginx 的
- 缓存键设计问题:
- 如果缓存键设计不合理(如包含过多变量),可能导致缓存对象过多
- 文件系统开销:
levels=1:2
的目录结构会产生额外存储开销- 小文件过多会浪费 inode 和块空间
解决方案
- 主动缓存清理:nginx复制下载proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off purger=on purge_all=on;
- 更频繁的缓存清理:
- 减少
inactive
时间(如从 7d 改为 1d) - 设置更小的
max_size
作为缓冲
- 减少
- 定期维护脚本:bash复制下载# 手动清理缓存 find /www/server/nginx/proxy_cache_dir* -type f -delete
- 监控和报警:
- 设置监控脚本检查缓存目录大小
- 达到阈值时触发清理
- 优化缓存键:nginx复制下载proxy_cache_key “$scheme$request_method$host$request_uri”;
- 调整文件系统:
- 使用更适合小文件存储的文件系统(如 ext4 调整 inode 数量)
- 考虑使用 SSD 提高缓存性能
您可能需要结合多种方法来解决缓存超标问题,特别是对于高流量网站。
为啥发现40天以前的缓存文件还在呢,超过了7天也没有被删除呢?
您的 Nginx 缓存中仍然存在超过 inactive=7d
设置的旧文件(如40天前的),这通常是由以下几个原因造成的:
主要原因分析
inactive
的工作机制问题:inactive=7d
表示 “未被访问的” 缓存文件在7天后会被删除- 如果文件被定期访问(即使是通过 Nginx 内部检查),它的时间戳会被更新,导致不会被清理
- 某些爬虫或扫描工具访问旧资源也会重置时间戳
- 缓存清理的惰性特性:
- Nginx 不会主动扫描并删除所有过期缓存
- 只有当缓存空间接近
max_size
时才会触发清理,且是逐步进行的
- 缓存路径权限问题:
- 如果 Nginx 工作进程(通常是
www-data
或nginx
用户)没有写入权限,可能导致清理失败
- 如果 Nginx 工作进程(通常是
- 自定义的
proxy_cache_key
问题:- 如果缓存键包含变量(如
$args
或$cookie
),可能生成大量重复内容的缓存,占用空间但不被清理
- 如果缓存键包含变量(如
解决方案
1. 强制立即清理缓存(手动)
# 手动删除超过7天的缓存文件(强制执行)
find /www/server/nginx/proxy_cache_dir* -type f -mtime +7 -delete
2. 优化 Nginx 配置
proxy_cache_path /www/server/nginx/proxy_cache_dir
levels=1:2
keys_zone=cache_one:50m
inactive=7d
max_size=500g
use_temp_path=off
purger=on; # 启用主动清理器
# 添加以下参数强化清理
proxy_cache_background_update on;
proxy_cache_use_stale updating;
3. 添加定时任务(Cron)
# 每天凌晨3点清理过期缓存
0 3 * * * find /www/server/nginx/proxy_cache_dir* -type f -mtime +7 -delete
4. 检查缓存键设计
proxy_cache_key "$scheme$host$request_uri";
5. 监控缓存目录
# 检查各缓存目录实际大小
du -sh /www/server/nginx/proxy_cache_dir*
终极方案:使用第三方工具
如果问题持续,可以考虑:
nginx-cache-purge
模块proxy_cache_purge
指令配合定期请求- 专用缓存管理工具如 CacheGuard
通过以上方法,您应该能解决旧缓存未被自动清理的问题。关键点在于理解 Nginx 的缓存清理是惰性的,需要手动干预或配置更积极的清理策略。
我只需要将inactive=7d改为inactive=1d,然后重启nginx,他会自动删除超期的吗?
是的,将 inactive=7d
改为 inactive=1d
并重启 Nginx 后,Nginx 会开始自动删除超过1天未访问的缓存文件,但需要注意以下几点:
1. Nginx 缓存清理的机制
- 惰性清理:Nginx 不会立即 删除所有超期的文件,而是在以下两种情况下触发清理:
- 当新缓存需要空间(快达到
max_size
时)。 - 缓存管理器后台扫描(低优先级,逐步进行)。
- 当新缓存需要空间(快达到
- 时间基准:
inactive=1d
表示如果某个缓存文件 1天内未被访问(Last Used
时间),它会被标记为可删除,但实际删除可能稍晚。
2. 如何验证是否生效?
✅ 方法1:检查缓存目录文件时间
# 查看缓存文件的访问时间(atime)
find /www/server/nginx/proxy_cache_dir -type f -printf "%AY-%Am-%Ad %AH:%AM %p\n" | sort
- 如果发现超过1天未访问的文件仍然存在,说明 Nginx 还未清理(惰性机制)。
- 如果文件被自动清理,你会看到旧文件逐渐减少。
✅ 方法2:观察磁盘空间变化
watch -n 60 "du -sh /www/server/nginx/proxy_cache_dir"
如果缓存量开始下降,说明清理机制已生效。
3. 如何立即触发清理?
如果不想等待 Nginx 自动清理,可以手动干预:
🔧 选项1:强制删除超期文件
# 删除超过1天未访问的缓存文件
find /www/server/nginx/proxy_cache_dir -type f -atime +1 -delete
🔧 选项2:让 Nginx 主动清理(需额外配置)
在 nginx.conf
中添加:
proxy_cache_background_update on;
proxy_cache_revalidate on;
然后重启 Nginx。
4. 注意事项
- 重启 Nginx 是必要的,否则配置不会生效。
- 如果缓存仍在增长,可能是:
- 访问量太大,新缓存生成速度 > 旧缓存清理速度。
max_size
设置过高,Nginx 不急于清理。- 文件系统
atime
未更新(检查mount
是否用了noatime
)。
5. 终极建议
如果希望 严格保证1天后删除,建议:
- 设置
inactive=1d
。 - 每天用 Cron 任务 补刀清理:
# 每天凌晨2点强制清理
0 2 * * * find /www/server/nginx/proxy_cache_dir* -type f -atime +1 -delete
这样既能利用 Nginx 自动清理,又能确保无残留。