报错是这么冒出来的。缓存目录按 key 直接存文件,攒了两百多万个,ls 要几分钟才返回,rm 直接卡住不动,磁盘 IO 一直被打满。
排查方向其实有限,先把可能性排一排。单个目录的文件数超出了文件系统索引的高效范围。少数情况下是删除时产生大量元数据事务,把 IO 全部占满。
少数情况下是应用没有按日期或者哈希分目录,全堆在同一层。
先停写入,避免边删边写
systemctl stop cache_worker
随后用 find 分批删除降低压力
find /data/cache -type f -delete
降 IO 优先级后继续清理
ionice -c3 find /data/cache -type f -delete
等前面都确认过,再确认剩余结构并改造成两级目录
find /data/cache -maxdepth 1 -type d | head
那几天正好在做别的变更,先把时间线对齐才敢动手。
恢复的判定其实很直接。目录文件数降到万级,ls 秒开,删除期间 iostat 不再持续满负荷。
rm 一个两百万文件的目录会长时间占着元数据锁,分批删比一次删完安全;根治还是要靠改目录层级设计。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。