磁盘告警来的时候,通常是你最不想处理服务器的时刻:可能刚准备下班,可能正在开会。登上机器敲个命令半天没反应,部署脚本报错提示空间不足,你才意识到问题比想象中严重。这时候最常见的手是去删文件,但删之前有几件事值得先确认,顺序错了就是白干一轮。
第一步不是找大文件,而是看清哪里满了。服务器上通常有多个挂载点,根分区、数据盘、日志盘各自独立,满载的很可能不是你以为的那个。用查看文件系统的命令扫一眼各分区的使用率,同时再查一次inode使用率——后者容易被忽略,它统计的是文件数量而不是字节数,一个目录里堆了海量小文件时,字节还空着,inode可能已经用光。这两个指标要一起看,只看其中一个都可能得出错误结论,比如空间还宽裕就以为没事,实际上已经写不进新文件了。
磁盘满了先分清,是空间不够还是inode不够
这两种情况的处理方式完全不同。空间不够,要清的是大文件;inode不够,要清的是大量小文件,可能每一张都不大,但几十万个加起来就把它占满了。缓存目录、会话文件、临时文件、邮件队列,是这类问题的常见来源。如果上来就按“找大文件”的思路排查,很可能找半天也找不到凶手,因为凶手不是一个文件,而是一群文件。
确认了是哪一种,再去找占用大户。从根目录开始逐级查看各子目录的大小,一层层往下钻,通常几步之内就能锁定目标。命令行上有现成工具,也可以在终端里用一个交互式的磁盘分析工具直接扫,它会按大小排序呈现,比手动一层层翻快得多。扫的时候注意一点:有些目录是系统挂载进来的,扫描时会报一堆权限错误,忽略它们即可,真正要关注的是可写的数据分区和日志分区。
找到大目录之后先别急着删,看清楚里面是什么再动手。日志、备份、构建产物、容器镜像、包管理器的缓存,这几类占了绝大多数情况。备份和构建产物通常可以直接清理,包缓存也有对应的命令可以安全清掉;日志要分情况,这就引出了下一个必须知道的区别。还有一类容易被当成垃圾删掉的东西值得留意:正在被服务引用的模型文件、数据文件,看着像重复资源,删了服务当场报错,清理前先确认没有进程在引用它。
正在写的日志不能直接删掉
日志是最常见的元凶,也是最容易处理错的一类。已经归档、被轮转过的旧日志,比如带序号或者压缩过的那些,直接删除没有风险。但正在被程序持续写入的当前日志文件不一样:如果你直接把它删掉,正在写它的进程还持有这个文件的句柄,磁盘空间不会立刻释放,而你在目录里又找不到这个文件——于是就出现了“容量显示没降、也找不到大文件”的诡异局面。
正确做法是清空而不是删除。把正在写的日志文件内容截断为空,进程继续往这个文件写,空间当场释放。这个操作不会打断服务,也不会破坏文件句柄,是处理活跃日志的标准做法。如果一时手快已经删了也还有救:找出仍持有句柄的进程,重启它就能释放;业务不允许重启的,可以进到进程的文件描述符目录里,把对应的描述符清空。
除了应用日志,系统日志还占着一块。按时间累积的系统日志由日志管理服务统一收集,可以用它自带的命令查看占用了多少,并设置一个容量上限,超出的旧日志会被自动清掉。也可以直接在配置文件里写死上限,让它长期生效。很多人从来没查过这块占用,实际上它涨到几个GB相当常见。这一块的好处是可以设上限,一旦设好就不需要再操心,系统会自己把最旧的日志清掉,比人工定期清理可靠得多。
另外几类也顺手清理一下。包管理器会缓存下载过的安装包,清一次往往能腾出可观空间;老版本的内核会留在系统分区里,可以只保留最近一两个;跑容器的话,镜像、已停止的容器和构建缓存是隐形大户,用它自带的统计命令看总占用,再清理未使用的资源。这几步做完,多数磁盘告警都能解除。
还有两种不常见但很坑的情况值得知道。一种是同一个目录被挂载了两次,后挂载的设备把先挂载的内容盖住了,数据其实写进了那个被隐藏的分区,这种情况用常规命令看不出异常;另一种是“空间不足”的报错其实跟磁盘无关,而是文件监视数量达到上限导致的,它报的错一样,原因却完全不同。排查到后面还是找不到原因时,不妨往这两个方向想一下。
比清理更重要的是让它别再发生。监控里把磁盘水位设成到八成告警,而不是等它满;确认日志轮转覆盖了每一个应用,包括自己写的服务;给系统日志设一个容量上限。这三件事做齐,磁盘告警会从“半夜的紧急事件”变成“白天的例行维护”,你也就不会再有那种半夜被叫起来删文件的经历。顺带说一句,清理动作本身也值得留个记录:什么时候清了什么、腾出了多少,时间久了你会看出增长规律,提前预判下一次告警大概什么时候来。
A5创业网 版权所有