缘起
我们测试环境中的一台Job机器磁盘空间使用率一直很高(VM 40G),最近经常遇到磁盘空间已满,导致一些任务无法正常运行,比如新项目的代码无法部署,影响正常的开发流程。几天前为赶项目进度,我们采用临时清理一些日志文件的方式,仅仅空出几G的空间,只能缓解一时,隔天又满了。总是这样就也太坑了,我决定花些时间彻底解决一下,不管采用什么办法。早晨起床后,我在Doit.im中创建了项目,并进行一些规划,列出一些需要进行的任务。
我对这台机器的职责并不熟悉,我猜测会否是该机器上部署了太多的服务导致,如果是这样,就将它们迁移出去;如果是因为机器配置太低的原因,则切换到配置更高的机器;迁移的话就需要对该机器上运行的任务进行梳理……
实战
到公司后,又听到该机器磁盘已满,又是临时的清理了些空间。我跑去测试环境的维护人员哪里,督促他解决这个问题,之后就待在那里和他一起解决。
- 首先,确认了这台机器只是作为Job机器,没有其他的服务。那么问题在哪里呢?
- 使用
du -sh /path
命令逐级缩小查找范围,期间也删除了一些小的日志文件,最终发现了一个16G+的nohup.out
日志文件。 - 终于找到罪魁祸首了,果断
rm nohup.out
删除掉它。咔,发现磁盘空间并没有被释放掉。这是什么情况? - 分析后发现,因为写入这个日志文件的进程还在执行导致的。那么,怎样定位这个进程呢?
- 我首先尝试使用
ps aux | grep _cmd_
命令,发现没有与该目录下文件名匹配的进程;接着我尝试遍历/proc
目录下所有进程的fd
目录,命令:find /proc -name fd -type d | grep nohup.out
,方法可行。 - 这时瞄一眼同事的屏幕,神器出厂,lsof,
lsof | grep nohup.out
即可,还可以显示文件的状态,被我删除的文件后缀有(deleted)
。 - 定位到进程pid后,在使用
ps -p pid
查看进程的命令;kill
关闭进程,nohup
重启命令,日志文件重定向到/dev/null
,磁盘空间瞬间释放了 😉 lsof
命令的结果显示,还有很多其他的nohup.out
文件存在,它们也将被逐个清理掉。
反思
虽然上面的过程可以在解决问题,但是这是一个折腾的过程,我们需要如何避免类似的问题?
- 使用
nohup
启用命令时,将日志重定向到指定的目录下或者/dev/null
; - 对于Job的日志,最好是在代码中调用日志接口,写入到指定目录,同时按照日期进行分割,这样方便以后的清理。
遗留问题
- 使用
ls -al
查看/proc
下的文件描述符(fd),发现它们是软连接(lr-x——),为什么删除掉文件后,磁盘空间没有被释放呢?(SegmentFault)