决策树
- 原始数据小于 2 MB → Gzip(差异小于 4ms,不值得引入依赖)
- 原始数据 2-5 MB → Gzip(差异小于 10ms,零依赖更重要)
- 原始数据 5-20 MB → Zstd(差异 10-45ms,开始有意义)
- 原始数据大于 20 MB → Zstd(差异大于 45ms,明显优势)
- Gzip 1.2 能否被 Zstd 替换?
结论:完全可以,且在绝大多数场景下是升级而非平替。
兼容性:Zstd 从 1.0 开始格式已稳定,向后兼容。现代 Linux 发行版、容器运行时、大数据生态(Hadoop/Spark/Kafka)均已原生支持 Zstd。
性能对比:即使对标 Gzip 1.2(一个较老的版本),Zstd 在同等压缩比下速度快 3-5 倍;同等速度下压缩比高 10%-30%。
唯一阻碍:如果目标环境是极度老旧的嵌入式设备或无法更新的基础设施(如仅支持 gzip 的旧版 Nginx/CDN),则不能替换。否则,无脑换 Zstd。(当前博客是基于团队惯性技术栈的决策方案,先对大文件进行技术栈迁移,如果看客想要做的话,直接使用zstd 做就行)
决策矩阵
| 场景 | 数据量 | 网络 | 读频率 | 推荐 | 原因 |
|---|---|---|---|---|---|
| 小型缓存(配置、字典) | 小于 2 MB | 任意 | 任意 | Gzip | 差异在噪声内,零依赖 |
| 中型缓存(用户画像) | 2-10 MB | 同机房 | 中 | Gzip | 差异小于 20ms,简单优先 |
| 大型缓存(离线菜单) | 10-50 MB | 同机房 | 高 | Zstd | CPU 是瓶颈,zstd 省 38% |
| 超大缓存(商品目录) | 大于 50 MB | 任意 | 高 | Zstd | 解压耗时大,zstd 优势明显 |
| 离线写入 + 在线读取 | 任意 | 任意 | 高 | Zstd-19 | 写入慢无所谓,内存最省 + 解压最快 |
| 流式传输(gRPC/HTTP) | 任意 | 慢链路 | - | Gzip | 压缩率略好,省带宽 |
核心判断原则
总耗时 = 网络传输 + 解压(CPU) + 业务映射
- 网络是瓶颈(跨机房、慢链路)→ Gzip,压缩率略好,传输量更少
- CPU 是瓶颈(同机房、本地缓存)→ Zstd,解压快 1.6 倍
- 内存是瓶颈(Redis 内存紧张)→ Zstd-19,体积比 gzip-9 还小 8%
- 数据量小(小于 5 MB)→ Gzip,差异小于 10ms,不值得引入原生库
- 写入不频繁 + 读取频繁 → Zstd-19,写入慢无所谓,读取最快
Zstd 级别选择
| 级别 | 压缩后大小 | 压缩率 | 压缩耗时 | 解压耗时 | 适用场景 |
|---|---|---|---|---|---|
| 1 | 8.03 MB | 23.3% | 198 ms | 129 ms | 在线实时压缩,追求速度 |
| 3 | 7.69 MB | 22.3% | 258 ms | 133 ms | 默认推荐,平衡压缩率与速度 |
| 9 | ≈7.4 MB | ≈21.4% | ≈800 ms | 128 ms | 与 gzip-9 相当的压缩率 |
| 19 | 6.81 MB | 19.7% | 14471 ms | 126 ms | 离线写入,体积最小 |
关键事实:Zstd 的解压速度与压缩级别几乎无关。Zstd-1 和 Zstd-19 的解压耗时几乎相同(129ms vs 126ms)。级别只影响压缩耗时和压缩率。
选择规则
- 在线实时写入(用户请求链路)→ Zstd-3
- 离线批量写入 (定时任务、数据同步)→ 离线 40M 文档,直接用
zstd -8即可。若实测耗时可接受则升至-9,若偏慢则降至-7,无需纠结其他等级。建议先使用zstd -9,看下和当下生产写入的时间进行对比 - 不确定 → Zstd-3(万能默认值)
每 MB 原始数据的解压耗时
| 算法 | 每 MB 耗时 | 说明 |
|---|---|---|
| Gzip(任意级别) | ≈6.0 ms/MB | 级别不影响解压速度 |
| Zstd-3 | ≈3.9 ms/MB | 比 gzip 快 1.6 倍 |
| Zstd-19 | ≈3.7 ms/MB | 解压速度与级别无关 |
| Raw(仅 parseFrom) | ≈2.5 ms/MB | 理论下限 |