软件吧
登录注册账号
/posts/tar
电脑必备

日志打包发回来解压卡了半小时,才发现tar参数顺序写反了

码农小张 86 0 13

先说结论:不是解压软件慢,是我自己写的打包命令参数顺序有问题,导致解压时走了最慢的路径。

背景:我们线上服务每天凌晨切日志,一个节点一天的日志压缩后大概 2GB 左右,200 个节点,运维统一用 tar.gz 打包回传。之前一直用 tar -czf 打包、tar -xzf 解压,没人觉得慢。上周我负责做一个日志分析脚本,需要频繁解包,结果一个 2GB 的包解了快半小时,CPU 还跑满了。

排查过程:

  1. 先换机器。拿三台同配置的测试机(都是 CentOS 7.9,内核 3.10),分别用 7-Zip 和 Win解压缩的命令行版本解同一个包,时间都在 4 分钟左右。说明不是软件的问题。
  2. 再看命令。我翻出打包脚本,发现当初写的是 tar -czf logs.tar.gz ./logs/ --exclude=*.tmp。问题就出在参数顺序:--exclude 放在目标目录后面,GNU tar 其实能识别,但有些老版本会忽略,等于把 tmp 文件也打进去了,包体积大了 30%。
  3. 更关键是解压端。我习惯用 tar -xzf logs.tar.gz -C /data/logs/,但 /data/logs/ 在机械盘上,而解压过程是边读边写,随机 IO 很多。我换成先解到 /dev/shm 再 mv 过去,时间从 28 分钟降到 6 分钟。

数据对比(三台同配置机器,同一 2.8GB 包):

  • 机械盘直接解压:平均 27 分 12 秒
  • 先解到 tmpfs 再 mv:平均 6 分 40 秒
  • 7-Zip 直接解压到机械盘:平均 8 分 15 秒

所以结论有两个:一是 tar 参数顺序要规范,--exclude 一定放在文件列表前面;二是解压路径的 IO 类型影响巨大,机械盘随机写是最大瓶颈。Win解压缩确实快,但它默认走的是多线程解压,对机械盘反而容易造成 IO 争抢,这点在服务器场景下要留意。

建议:

  • 打包命令统一写成 tar --exclude='*.tmp' -czf logs.tar.gz ./logs/,参数顺序固定下来
  • 服务器解压优先用 tmpfs 中转,前提是内存够
  • 如果是机械盘,解压前先 ionice -c 3 降优先级,避免影响线上服务

最后问一句:你们日志包一般多大?有没有人试过用 zstd 替代 gzip 打包,解压速度能快多少?我这边测下来 zstd 解压确实快 2 倍左右,但老系统装 zstd 要折腾依赖,想听听大家的实际经验。

登录后可以为帖子点赞,但本帖内容对所有人开放阅读。

社区回应

0 Replies

还没有回应,抢一个沙发。

登录后可以回应和点赞,但本帖内容对所有人开放阅读。

日志打包发回来解压卡了半小时,才发现tar参数顺序写反了