磁盘写满,最先受影响的是写入而不是访问
站点在高负载下彻底宕机的概率其实不高,更常见的情况是磁盘悄悄写满。静态页面还能靠缓存勉强顶着,但一旦涉及写入,问题会集中爆发:数据库事务失败、session 与缓存无法落盘、上传目录拒绝写入、临时文件创建不出来,日志文件也不再产生新内容。对访客来说可能是白屏或报错;对搜索蜘蛛来说,就是成批的 5xx 响应。抓取程序遇到连续错误会主动降低抓取频率,部分地址还可能被临时标记为抓取失败,恢复需要时间。
更麻烦的是,日志写不进去,排查依据也就没了——蜘蛛来过没有、抓了哪些地址、返回什么状态码,全都无从查起。
先做一次空间盘点
不要急着删文件,先弄清空间去了哪。按下面顺序走一遍,通常几分钟就能定位。
- 整体水位:查看各挂载点的使用率与剩余量,数据盘、日志盘、备份盘要分开看。
- 按目录排序:从根目录往下逐层统计,找出占用量最大的两三个目录。
- 找大文件:定位超过百兆的单文件,常见的是旧备份、数据库文件、压缩包、核心转储。
- 看 inode:小文件过多同样会耗尽 inode,此时磁盘显示还有空间,但新文件依旧创建失败。
日志轮转该配到什么程度
访问日志是最容易被忽略的增长源。一个中等规模的站点,几天的原始 access log 就能吃掉好几个 G。轮转策略建议落在这几个参数上:
- 按天或按体积切割,两者取先到者,避免突发流量把单个文件撑爆。
- 明确保留份数,保留 7 到 14 天通常够用;需要长期留存的日志应转存到别的机器或对象存储,而不是一直堆在本机。
- 开启压缩,纯文本日志的压缩比一般相当可观。
- 切割后要让服务重新打开日志文件,否则进程仍握着旧句柄,新文件是空的(nginx 通常需要发送 USR1 信号)。这是很常见的一处坑。
提醒:正在被进程写入的日志文件,直接删除往往不会立刻释放空间。空间要等句柄关闭才回收,表现为「明明删了,用量却没降」。正确做法是先轮转、再清理。
把蜘蛛日志单独管理
如果主要关心蜘蛛的抓取行为,可以按 User-Agent 把蜘蛛请求单独输出到一个日志文件,主日志只保留普通访客请求。这样有两个好处:蜘蛛日志体积小、翻查快;主日志的轮转压力也随之下降。
但要注意两点:一是单独输出的日志同样需要轮转规则,别让它变成新的增长点;二是不要为了省空间把日志写到内存盘却不做落盘,重启即丢,反而让分析断档。流量很大的站点可以只保留状态码、URL、UA 和时间这类精简字段。
留出水位,加上告警
靠人工定期查看迟早会漏,建议把几个阈值交给监控:
- 磁盘使用率到 80% 提醒,90% 告警。
- inode 使用率同样监控,与容量告警分开配置。
- 日志目录单独监控增长速度,突增往往意味着被刷或被异常抓取。
- 预留一定比例空间给数据库临时文件和备份,不要等到最后一格。
一份可执行的检查清单
- 确认各挂载点剩余空间与 inode 情况。
- 定位占用最大的目录与大文件,判断哪些可清理、哪些应归档。
- 检查轮转规则是否覆盖所有日志文件,包括自建服务的输出。
- 验证轮转后服务是否正确重新打开日志,新文件是否有写入。
- 清理策略改为轮转加归档,不再直接删除正在写入的文件。
- 补齐水位与 inode 告警,并写明处理人。
- 抽查蜘蛛请求的状态码分布,确认没有因磁盘问题堆积的 5xx。
磁盘和日志属于最不显眼的那部分工作,出问题时也很少有人第一时间想到它。把这几项做成固定检查,比事后救火省事得多。