多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

磁盘还剩 400 多 GB,系统却喊着没地方写文件——这回连“户口本“都是满的

磁盘还剩 400 多 GB,系统却喊着没地方写文件——这回连“户口本“都是满的 上篇写完文件描述符我在结尾预告了一个更安静的死法——磁盘明明没存多少东西空间却满了。结果话音落下没几天我自己就撞上了真人版客户的影像归档系统凌晨批处理集体失败报错清一色是 No space left on device设备上没有剩余空间。运维小哥打电话过来的时候语气都快哭了磁盘四百多个 G 的空地空着它凭什么跟我说满我到现场先自己摸了一遍。df -hdisk free看磁盘剩余空间的命令显示 500G 的盘才用了 47G空得能跑马换个目录写文件还是报同一个错。再用 dudisk usage统计各目录实际占了多少空间一层层翻下去没有任何一个目录异常膨胀。大文件嫌疑、日志暴涨嫌疑、备份写穿嫌疑挨个排除。排除到最后我想起上篇 fd 的教训常规嫌疑人都干干净净的时候剩下的那个往往是最没存在感的。df -h 看的是仓库df -i 看的是户口本。后者一跑出来真相大白IUse%inode 使用率100%八百二十万张卡一张不剩。户籍卡这个词不是我随口打的比方。inode索引节点就是文件系统给每个文件发的卡——文件多大、谁有权限读、数据实际躺在哪几个磁盘块上全写在卡上。有个反直觉的细节文件名压根不住在卡上它登记在目录里卡和名字是分开两本账。所以上篇结尾我说连文件名本身都成了负担严格讲不严谨负担是卡不是名字。而这里真正要记住的规则只有一条一个文件占一张卡文件再小哪怕只有一个字节卡也照占。卡的总量在格式化那会儿基本就定死了ext4Linux 上最常见的文件系统格式默认按文件平均个头比较大来配卡粗算是每 16KB 空间配一张。于是几百万个小文件涌进来空间还没看见影儿卡先发光了。仓库明明有地户籍科发不出新户口新货就是进不了场。接着揪是谁在囤卡。find / -xdev -type ffind 是找文件的命令-xdev 表示只在当前文件系统里翻别把挂载的其它盘也捎上按目录统计文件个数一路排除最后停在 /data/queue/retry/七百多万个几 KB 的小 json全在里头蹲着。顺便打岔一句我在那个目录里敲了个 ls回车之后屏幕僵了快半分钟才吐出结果——八百万个文件连点名这件事本身都是一场小型灾难。这堆小文件的来历查完我哭笑不得。半年前上游接口不稳客户加了个重试逻辑任务失败就往 retry 目录落一个 .retry 文件等后面补跑。又配了个清理脚本说好只删 30 天以前的旧文件。结果脚本里日期匹配写错了一个字符正则从来没命中过半年下来一个都没删成。这病阴就阴在它是渐进的卡一张一张少下去平时任务照跑不误谁也察觉不到等最后一张卡被领走所有要写文件的环节一夜之间集体塌方而且塌得毫无征兆——没有任何一条日志会告诉你卡不够了。动手删。直接 rm删文件命令那批文件shell 甩给我一个 argument list too long参数列表太长——rm 一口气收到七百万个文件名当场噎住。换成 find /data/queue/retry -name *.retry -delete让它自己分批慢慢删删了小半个下午IUse% 从 100% 掉到 3%写入立刻满血复活。删完不是完事监控里我先把 df -i 的采集加进去跟 df -h 平级IUse% 超过 80% 就告警清理脚本也改了按文件修改时间判断新旧不再看文件名上游那个重试逻辑顺手重构成攒够一批再合并落盘小文件从源头上就少生了一多半。再说句诚实的话这病没有一劳永逸的药。有的系统天生就产出海量小文件——邮件队列、PHP 的 session 文件每个访客一份的会话数据、图床的缩略图都是这个体质。遇到这种要么配定期清理要么把小文件挪去对象存储要么格式化的时候用 -N 参数手动把卡多配一些。但改 inode 数量必须重新格式化属于伤筋动骨的手术千万别在半夜灵机一动。再打岔一回修完当天我鬼使神差地回自己电脑上也跑了个 df -i好家伙Home 目录的卡用掉六成全是这几年攒下的 node_modules前端项目的依赖目录小文件制造大户和缓存碎片。这病真不止服务器有你哪天自己的电脑突然喊磁盘已满、可照片视频明明没多大可以想起今天这篇。这套排查适合谁只要你管着任何一台跑 Linux 的机器就把 df -i 记进肌肉记忆成本就一条命令。要是你平时只在托管平台上写写函数碰不着文件系统那这篇当个冷知识看看也行。另外替它说句公道话xfs另一种常见的文件系统的卡是动态发的基本不会得这病但 ext4 的存量服务器还多得很别拿运气赌。现在再看 fd 和 inode 的区别就清楚多了fd 是进程手里临时的号牌进程一死全部上缴inode 是文件系统的户口文件不删卡就永远占着。一个管打开的东西一个管存在的东西。你呢有没有撞见过df -h 明明有空间、写入却喊满的灵异现场最后元凶蹲在哪个目录评论区聊聊——我赌一大半在 /tmp 和某个忘了清理的队列目录里。预告号牌讲过了户口也讲过了还有更瘆人的一种死法——进程明明已经死透了尸体却一直留在系统进程表里没人收越积越多最后把整台机器拖垮。下篇聊聊僵尸进程Zombie Process。
返回列表