133 MiB 访问日志压缩实测:zstd -19 慢 175 倍,每秒只省下 48 KiB

举报
yd_276135645 发表于 2026/11/11 06:33:30 2026/11/11
【摘要】 在 4 核机器上把 gzip / pigz / zstd / xz 的常用档位全部实测一遍:gzip -9 比 -6 多一倍 CPU 只省 0.6 MiB;pigz -6 与 gzip -6 体积几乎相同却快 3 倍;zstd -19 慢 175 倍、折算每秒只省 48 KiB,而多线程 xz 更小还快 3.5 倍。附解压吞吐对照与落地选型建议。

一次很常见的选型纠结

归档日志、打包 CI 产物、做镜像层压缩时,总会遇到同一个问题:压缩等级调多少?很多团队的做法是把等级直接拧到最大,理由是"反正是一次性开销,小一点总没坏处"。

本文用一台 4 核机器、一份 133.4 MiB 的真实形态访问日志(nginx 默认格式、带 UA 与 rt/upstream 字段),把 gzip / pigz / zstd / xz 的常用档位全跑了一遍。时间与体积来自同一轮测量,输入文件已预热进 page cache,所以下面比的是纯 CPU 成本,不是磁盘速度。

实测数据

工具与档位 耗时 压缩后 占原始 吞吐
gzip -1 1.18 s 22.82 MiB 17.1% 113 MiB/s
gzip -6 2.92 s 17.71 MiB 13.3% 46 MiB/s
gzip -9 6.09 s 17.11 MiB 12.8% 22 MiB/s
pigz -6 -p4 0.96 s 17.74 MiB 13.3% 139 MiB/s
zstd -1 0.45 s 19.97 MiB 15.0% 297 MiB/s
zstd -3 0.72 s 20.16 MiB 15.1% 185 MiB/s
zstd -3 -T4 0.30 s 20.16 MiB 15.1% 440 MiB/s
zstd -19 126.20 s 14.22 MiB 10.7% 1.1 MiB/s
xz -1 7.47 s 17.65 MiB 13.2% 18 MiB/s
xz -6 -T4 36.31 s 13.96 MiB 10.5% 3.7 MiB/s

结论一:档位不是线性的,gzip -6 → -9 是最亏的一档

从 -6 到 -9,CPU 时间翻倍(2.92 s → 6.09 s),体积只从 17.71 MiB 降到 17.11 MiB,绝对值省下 0.6 MiB,相对只小 3.4%。换句话说,多花的那 3 秒买到了 0.6 MiB。如果这份日志每天要压一次、保留 30 天,一年下来省 200 MiB 左右,而多耗的 CPU 时间约 19 分钟——不算灾难,但也没多少价值。

真正便宜的是低档位区间:gzip -1 用 1/5 的时间拿到 17.1% 的体积,压缩率只比 -9 差 4.3 个百分点。

结论二:多线程比调档位划算得多

同一档位 gzip -6,用 pigz -6 -p4 跑,体积只比单线程 gzip 大 0.17%(17.74 vs 17.71 MiB,是并行分块带来的边界损耗),时间从 2.92 s 掉到 0.96 s,快 3 倍。

在 4 核机器上继续调 gzip 的等级,本质是在用单核算力换百分比;而开多线程是在用闲置的算力换整块时间。zstd -3 -T4 更极端:0.30 s,440 MiB/s,比单线程 gzip -1 快 4 倍、体积还小 14%。

一个常被忽略的细节:gzip/zstd/xz 都支持多线程参数,但很多脚本里写的还是裸 gzip -9。如果你在 CI 里压缩产物,把命令换成 pigz -6 -p$(nproc) 通常就是一行改动、三倍收益。

结论三:极端档位的边际收益会崩掉

zstd -19 花了 126 秒,比 zstd -3 的 0.72 秒慢 175 倍,体积小 29.5%(20.16 → 14.22 MiB)。折算下来,多花的每一秒只省回约 48 KiB。

更值得注意的是对照:xz -6 -T4 只用 36 秒就压到 13.96 MiB,比 zstd -19 更小、还快 3.5 倍。也就是说,如果目标真的是"压到最小",多线程 xz 比单线程 zstd -19 更值得考虑(代价是 xz 的内存占用和解压速度,见下一节)。

解压侧:读路径比写路径更重要

压缩只发生一次,解压可能发生很多次。同一份数据解压到 /dev/null:

  • gunzip(gzip -6 产物):534 ms,250 MiB/s
  • zstd -dc(-3 产物):223 ms,598 MiB/s
  • zstd -dc(-19 产物):260 ms,513 MiB/s
  • unxz -T4(xz -6 产物):425 ms,314 MiB/s

zstd 的解压速度是 gzip 的 2.4 倍左右,而且几乎不受压缩档位影响。对于"每天压一次、每次发布都要解开"的场景,这个差距比压缩体积重要得多。

落地建议

  • 热数据、在线传输、容器层:zstd -3 -T0,够快也够小。
  • 只认 .gz 的老工具链:pigz -6 -p$(nproc),一行改动换三倍时间。
  • 冷归档、一年动一次:xz -6 -T0(或 zstd --ultra -19 --long=27),但请先确认机器内存扛得住。
  • 别再用裸 gzip -9 当默认值:它的性价比在这份数据里是最差的一档。
  • 决策时把"解压次数"算进去:一次性归档看体积,反复读取看解压吞吐。

复现很简单,把 access.log 换成你自己的日志:

for lv in 1 6 9; do
  /usr/bin/time -f "gzip -$lv %es" gzip -$lv -c access.log | wc -c
done
/usr/bin/time -f "pigz -6 %es" pigz -6 -p4 -c access.log | wc -c
/usr/bin/time -f "zstd -3 -T4 %es" zstd -3 -T4 -c access.log | wc -c

压缩档位不是"越大越好",而是一条边际收益递减的曲线。先确认你付的是 CPU 还是时间,再决定拧到哪一格。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。