删除百万级PHP会话文件时服务器宕机,求安全删除方案
兄弟,我太懂你这种删百万级文件搞崩服务的痛苦了!之前在Debian+Plesk环境里处理过几乎一模一样的场景——核心问题就是一次性操作瞬间占满IO和系统资源,把Nginx和PHP-FPM的资源挤没了,直接导致网关超时宕机。给你几个亲测有效的安全删除方案,按优先级来:
方案1:分批删除(最稳妥,优先推荐)
一次性删150万文件会瞬间打满磁盘IO,系统根本腾不出资源处理用户请求。咱们把删除操作拆成小批次,每次只删一部分,还给系统留喘气的时间:
用这个循环脚本就行,每次删1000个旧会话文件,删完暂停2秒,直到删完为止:
while true; do # 每次筛选出1000个超过1天的会话文件并删除 find /full/path/tmp/sessions -name "sess_*" -mtime +1 | head -n 1000 | xargs rm -f # 暂停2秒,降低IO压力 sleep 2 # 检查是否还有符合条件的文件,没有就退出循环 if [ -z "$(find /full/path/tmp/sessions -name "sess_*" -mtime +1 -print -quit)" ]; then break fi done
你可以根据服务器性能调整head -n的数量(比如改成500或者2000),也可以调整sleep的时间,确保删文件的时候网站还能正常访问。
方案2:给删除命令加IO优先级限制
如果不想写循环,也可以让删除操作“谦让”一点,只用系统空闲时的IO资源,这样就不会抢占Nginx和PHP的资源:
用ionice命令给find/rm设置最低IO优先级(空闲类):
# 直接用find -exec的方式 ionice -c 3 find /full/path/tmp/sessions -name "sess_*" -mtime +1 -exec rm {} \; # 或者结合xargs,效率更高一点 ionice -c 3 find /full/path/tmp/sessions -name "sess_*" -mtime +1 | xargs rm -f
ionice -c 3表示这个进程只有当系统没有其他IO请求时才会运行,完全不会影响线上服务的响应速度,就是删除速度会慢一点,适合低峰期执行。
方案3:从根源解决——让PHP自己管理会话垃圾(长远方案)
你现在手动删文件,本质是PHP自带的会话垃圾回收没起作用。在Plesk里调整PHP配置,让系统自动清理旧会话:
- 登录Plesk面板,找到对应的PHP版本(比如你网站用的PHP 5.6或者7.x),进入「设置」页面。
- 调整
session.gc_maxlifetime:设置为86400(即24小时),和你之前的-mtime +1对应,超过这个时间的会话会被标记为垃圾。 - 检查
session.gc_probability和session.gc_divisor:默认是1/100(每100个PHP请求触发一次垃圾回收),如果你的网站请求量不大,回收频率太低,可以改成5/100(不要改太高,避免影响请求性能)。 - 进阶方案:把会话存储从文件改成Redis/Memcached,这样完全不会有大量文件积累的问题,还能提升会话读取速度。Plesk里可以通过安装对应扩展,然后修改
session.save_handler配置实现。
额外注意事项
- 尽量在网站低峰期(比如凌晨)执行删除操作,进一步降低对用户的影响。
- 绝对不要用
rm -rf session/直接删目录:当目录下文件量极大时,rm会先遍历所有文件并加载到内存,直接导致内存和IO过载,瞬间搞崩服务。 - 可以用
find /full/path/tmp/sessions -name "sess_*" -mtime +1 | wc -l实时查看剩余待删文件数量,监控进度。
内容的提问来源于stack exchange,提问作者Panganino
相关产品推荐
相关产品推荐

