日志归档用 gzip 还是 zstd?174MB access.log 实测 8 档压缩
服务器上的日志一直是 logrotate 默认的 gzip 在压。最近归档目录越来越大,想换 zstd,但不想凭感觉换,于是拿一份 174MB 的访问日志把两边常用的几个级别都跑了一遍。
测试环境
- 系统:Debian GNU/Linux 13 (trixie),2 核,内存约 7.9G,没有 root
- 版本:gzip 1.13,zstd v1.5.7
- 样本:脚本生成的 Nginx combined 格式日志,1500000 行,182234902 字节(ls 显示 174M)
样本长这样,IP 用的是文档保留段:
$ head -2 access.log
203.0.113.243 - - [01/Nov/2026:00:00:00 +0800] "GET /api/v1/login HTTP/1.1" 200 3364 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/130.0"
203.0.113.138 - - [01/Nov/2026:00:00:00 +0800] "GET /api/v1/items HTTP/1.1" 200 4001 "-" "curl/8.5.0"
先说清楚一点:这是生成出来的日志,字段重复度和真实业务日志不完全一样,压缩比的绝对值只能参考,几档之间的相对关系才是重点。
测试脚本
一开始我想用 /usr/bin/time -v 顺便看内存峰值,结果脚本直接退出码 127,输出文件全是空的。这台机器是精简系统,压根没装 time 这个包,又没 sudo 装不上。干脆改用 bash 自带的 time 关键字,只记墙钟时间:
#!/usr/bin/env bash
# 用法: ./bench.sh access.log
f=$1; TIMEFORMAT=%R
for c in "gzip -1" "gzip -6" "gzip -9" "zstd -1" "zstd -3" "zstd -9" "zstd -3 -T0"; do
t=$( { time $c -c "$f" > out.tmp 2>/dev/null; } 2>&1 )
printf '%-12s %7ss %10s bytes\n' "$c" "$t" "$(stat -c %s out.tmp)"
done
rm -f out.tmp
TIMEFORMAT=%R 让 time 只输出一个秒数,方便塞进变量。zstd -19 没放进循环,原因后面说。

$ ./bench.sh access.log
gzip -1 1.059s 21187316 bytes
gzip -6 1.790s 15143711 bytes
gzip -9 5.557s 13715907 bytes
zstd -1 0.285s 19139328 bytes
zstd -3 0.391s 18935241 bytes
zstd -9 2.369s 13238587 bytes
zstd -3 -T0 0.260s 18935241 bytes
这组数字我前后跑了两轮,第二轮 zstd -3 是 0.391s,第一轮是 0.525s,波动不小;gzip 两轮几乎一样。小文件计时本来就容易抖,看量级就行。
压缩:体积和速度

几个让我意外的地方:
- zstd -3(默认级别)比 gzip -6 快 4.6 倍左右,但体积大 25%。如果只看默认值对默认值,zstd 在日志上并没有更省空间。
- 真正能比 gzip -6 小的是 zstd -9:13238587 对 15143711 字节,小了 12.6%,压缩耗时 2.369s 对 1.790s,只慢三成。
- gzip -9 很不划算:比 -6 多花 3 倍时间,只小了 9.4%,而且还比 zstd -9 大。
-T0开多线程后耗时从 0.391s 降到 0.260s,输出字节数完全一样。2 核机器上能有这个提升已经可以了。
zstd -19 跑了 217 秒
-19 我单独跑的,原以为几十秒就完事,结果等了 217.451 秒,得到 11791863 字节。比 -9 再小 11%,但耗时是 -9 的九十多倍。每天切一次日志的话,3 分多钟占着一个核还能忍;日志量再大一点就不现实了。所以它没进循环,不然每次跑脚本都得干等。
解压:差距最大的一项
归档的日志总有要翻出来查的时候,zcat | grep 的速度其实比压缩速度更影响体验。
$ TIMEFORMAT=%R
$ time (gzip -dc out.gzip-9 > /dev/null)
0.618
$ time (zstd -dc out.zstd-9 > /dev/null)
0.109
另外两个:gzip -6 解压 0.623s,zstd -3 是 0.129s,zstd -19 是 0.140s。gzip 不管压的时候用几级,解压都在 0.62s 上下;zstd 都在 0.1 秒出头,-19 压得那么狠,解压也没变慢。算下来 zstd 解压快 5 倍左右。

验证:压完能原样还原
速度再快,解不回原文件也没用。拿最狠的 -19 做一次往返校验:
$ md5sum access.log
d557650926e88a32bd4373fbea8dc313 access.log
$ zstd -dc out.zstd-19 | md5sum
d557650926e88a32bd4373fbea8dc313 -
$ gzip -t out.gzip-6 && echo ok
ok

两边 md5 一致。gzip -t 和 zstd -t 都能只校验不落盘,放在归档脚本最后一步挺合适。
怎么选
- 只想要更快、不在乎体积:zstd -3 加
-T0,比 gzip -6 快好几倍,体积大一些。 - 想同时省空间和时间:zstd -9,比 gzip -6 小 12% 左右,压缩略慢,解压快 5 倍。我自己的归档会换成这个。
- zstd -19 只适合一次性的冷备份,日常轮转别用。
- gzip -9 没有使用场景,要么 -6,要么直接换 zstd。
- 换之前确认下游工具认 .zst:
zstdcat、zstdgrep都有,但有些老脚本写死了zcat,这步别省。
- 点赞
- 收藏
- 关注作者
评论(0)