磁盘寫满,最先受影响的是寫入而不是訪問
站点在高负载下彻底宕机的概率其實不高,更常见的情况是磁盘悄悄寫满。静態頁面還能靠缓存勉强顶着,但一旦涉及寫入,問题會集中爆發:資料库事務失敗、session 與缓存無法落盘、上传目錄拒绝寫入、临时文件建立不出来,日誌文件也不再产生新内容。對訪客来说可能是白屏或报错;對搜尋蜘蛛来说,就是成批的 5xx 响應。抓取程序遇到连續错誤會主動降低抓取频率,部分地址還可能被临时标记為抓取失敗,恢复需要時間。
更麻烦的是,日誌寫不進去,排查依據也就没了——蜘蛛来過没有、抓了哪些地址、返回什么狀態碼,全都無從查起。
先做一次空間盘点
不要急着删文件,先弄清空間去了哪。按下面顺序走一遍,通常几分钟就能定位。
- 整体水位:查看各挂载点的使用率與剩余量,資料盘、日誌盘、备份盘要分開看。
- 按目錄排序:從根目錄往下逐层統計,找出占用量最大的两三個目錄。
- 找大文件:定位超過百兆的單文件,常见的是舊备份、資料库文件、压缩包、核心轉储。
- 看 inode:小文件過多同样會耗尽 inode,此时磁盘顯示還有空間,但新文件依舊建立失敗。
日誌轮轉该配到什么程度
訪問日誌是最容易被忽略的增長源。一個中等規模的站点,几天的原始 access log 就能吃掉好几個 G。轮轉策略建议落在這几個參數上:
- 按天或按体积切割,两者取先到者,避免突發流量把單個文件撑爆。
- 明确保留份數,保留 7 到 14 天通常够用;需要長期留存的日誌應轉存到別的机器或對象存储,而不是一直堆在本机。
- 開啟压缩,纯文本日誌的压缩比一般相当可观。
- 切割後要让服務重新打開日誌文件,否則進程仍握着舊句柄,新文件是空的(nginx 通常需要發送 USR1 信号)。這是很常见的一處坑。
提醒:正在被進程寫入的日誌文件,直接刪除往往不會立刻释放空間。空間要等句柄關閉才回收,表現為「明明删了,用量却没降」。正确做法是先轮轉、再清理。
把蜘蛛日誌單獨管理
如果主要關心蜘蛛的抓取行為,可以按 User-Agent 把蜘蛛請求單獨輸出到一個日誌文件,主日誌只保留普通訪客請求。這样有两個好處:蜘蛛日誌体积小、翻查快;主日誌的轮轉压力也随之下降。
但要注意两点:一是單獨輸出的日誌同样需要轮轉規則,別让它變成新的增長点;二是不要為了省空間把日誌寫到内存盘却不做落盘,重啟即丢,反而让分析断档。流量很大的站点可以只保留狀態碼、URL、UA 和時間這類精简字段。
留出水位,加上告警
靠人工定期查看迟早會漏,建议把几個阈值交给监控:
- 磁盘使用率到 80% 提醒,90% 告警。
- inode 使用率同样监控,與容量告警分開配置。
- 日誌目錄單獨监控增長速度,突增往往意味着被刷或被異常抓取。
- 预留一定比例空間给資料库临时文件和备份,不要等到最後一格。
一份可执行的检查清單
- 確認各挂载点剩余空間與 inode 情况。
- 定位占用最大的目錄與大文件,判断哪些可清理、哪些應归档。
- 检查轮轉規則是否覆盖所有日誌文件,包括自建服務的輸出。
- 驗證轮轉後服務是否正确重新打開日誌,新文件是否有寫入。
- 清理策略改為轮轉加归档,不再直接刪除正在寫入的文件。
- 补齐水位與 inode 告警,並寫明處理人。
- 抽查蜘蛛請求的狀態碼分布,確認没有因磁盘問题堆积的 5xx。
磁盘和日誌属于最不顯眼的那部分工作,出問题时也很少有人第一時間想到它。把這几項做成固定检查,比事後救火省事得多。