数据压缩算法没有绝对的“最优”,只有和你的计算资源、存储成本匹配的“最划算”,选错了,要么CPU烧钱,要么存储浪费;选对了,同样的硬件能多装几倍数据,查询还不见得慢。
数据压缩算法怎么选才划算?先看账怎么算
很多团队选压缩算法,只盯着“压缩率”这一个指标,压缩率只是表面文章,真正决定性价比的,是压缩率、压缩速度、解压速度这三者,还要加上你的硬件成本和业务访问模式。
举个常见例子:同样一份日志文件,用gzip最高等级压缩,体积确实最小,但压缩时CPU飙到满载,耗时是低等级的好几倍,如果日志每天产生几TB,光压缩这一道工序,就要额外占用大量计算资源,反过来,用LZ4,速度极快,但压缩率低,存储成本就上去了,这里面的权衡,计算与存储的性价比”的核心。
不同的数据特征,对应完全不同的算法
没有万能算法,只有适合你数据形态的算法,这里分几种典型情况:
- 文本型数据(日志、JSON、XML):重复模式多,适合用zstd或brotli,zstd在压缩率和速度之间平衡得非常好,brotli对文本的压缩率更高,但速度稍慢。
- 数值型数据(数据库列、监控指标):整列数值往往有规律,gzip和zstd都行,但更推荐zstd,它支持字典训练,对固定模式的数值序列效果更好。
- 已压缩数据(图片、视频、二次压缩):直接用LZ4或snappy这类轻量级算法,它们不会试图再压缩已经压过的内容,能避免无效CPU消耗。
- 冷数据归档(一年前的备份、历史订单):这类数据读得少,追求极致体积,用gzip -9或xz(LZMA)更合适,压缩慢一点没关系。
压缩算法哪个性价比高?一张表看懂权衡
业内比较常见的几个算法,各自的“性格”差别很大,这里用相对值来对比,方便你结合实际场景评估:
| 算法 | 压缩率 | 压缩速度 | 解压速度 | CPU消耗 | 典型场景 |
|---|---|---|---|---|---|
| LZ4 | 低 |
极快 |
极快 | 极低 | 实时日志、缓存、消息队列 |
| Snappy | 低-中 | 很快 | 很快 | 低 | 大数据中间格式(如Parquet) |
| zstd | 中-高 | 快(可调等级) | 快 | 中 | 数据库表、列存、通用压缩 |
| gzip | 中 | 中(等级依赖) | 中 | 中 | 日志归档、HTTP传输、传统系统 |
| brotli | 高(文本) | 慢 | 中-快 | 高 | Web静态资源、文本密集型存储 |
| xz/LZMA | 极高 | 慢 | 中 | 极高 | 备份归档、安装包、冷存储 |
行业共识认为,zstd是目前大多数场景下“性价比”最均衡的选项,它在压缩率上接近gzip -9,但压缩速度快了几个数量级,解压速度更是有优势,很多数据库和大数据框架(如PostgreSQL、ClickHouse、Kafka)默认支持或推荐zstd,不是没有原因的。
从存储账单和CPU账单看压缩选型
选压缩算法不是技术自嗨,而是直接反映在两个账单上:存储账单和计算账单。
算清这笔账:一个具体场景推演
假设你有10TB原始日志,存储成本按云厂商对象存储约0.12元/GB/月计算(据某云厂商官网价格),不压缩时每月存储费约1200元,如果用zstd压缩到3TB体积,每月存储费降到360元,节省约840元,但压缩这些日志需要消耗计算资源,如果一次性压缩10TB数据,用zstd -3等级,单核处理速度约100MB/s,需要约10万秒CPU时间,折合28小时单核,按通用型云主机0.1元/核/小时算,成本约2.8元(实际上通常多核并行,总核时不变),这2.8元换来了每月840元存储费节省,值不值?显然值。
反过来,如果日志需要实时写入,压缩速度跟不上写入速率,就会造成数据积压,这时候用LZ4虽然压缩率低一些(可能压到5TB),但存储费也只多出约600元/月,而CPU成本几乎可以忽略,哪个更划算?取决于你的写入峰值和CPU余量。
压缩算法的“隐藏成本”:解压时的延迟
很多人只看压缩时的开销,忽略了解压延迟,对于在线查询系统(比如数据库、搜索服务),每次读取数据都要先解压,解压速度直接决定查询响应时间,LZ4解压极快,但压缩率低;xz解压慢,但体积小,对于需要频繁读的数据,宁可多花点存储费,也要保证解压速度,对于几乎不读的归档数据,则反过来。

选型不是一次性决定,而是要把数据分层:
- 热数据(频繁读):优先解压速度,用LZ4或snappy,甚至不压缩。
- 温数据(偶尔读):优先压缩率与解压速度平衡,用zstd -3到-5等级。
- 冷数据(很少读):追求高压缩率,用gzip -9或xz。
企业数据压缩方案推荐:从数据库到冷存储落地
这里按实际工作流给几套可落地的方案,覆盖最常见的几个场景。
数据库场景:OLTP与OLAP分开对待
- OLTP(高频点查):比如MySQL、PostgreSQL,行存场景下,压缩收益有限,且会拖累单行更新,建议只对不常更新的历史表启用压缩,或者用表级压缩选项,PostgreSQL支持多种压缩算法(pg压缩选项),OLTP下更推荐使用zstd,它对记录级压缩有优化。
- OLAP(批量分析):列式存储天生适合压缩,ClickHouse、Doris等数据库都支持列级压缩选型,行业实践是:主键列用LZ4,其他列用zstd,为什么?主键列需要频繁比较和过滤,LZ4解压快,其他列用来聚合计算,更看重压缩率。
实操步骤:在ClickHouse中创建表时,可以指定每列的压缩算法。
CREATE TABLE metrics (timestamp DateTime CODEC(ZSTD), value Float64 CODEC(LZ4))
ENGINE = MergeTree()
这样不同列用不同算法,兼顾查询性能和存储效率。
日志与消息队列场景:实时性优先
Kafka和日志采集端,数据写入频繁,消费者还需要快速追读,推荐默认使用LZ4或zstd -1,LZ4压缩率低但CPU占用极小,适合高吞吐的实时管道,zstd -1的压缩率比LZ4高不少,速度也很快,是更划算的选择。
实操验证:在Kafka中设置compression.type=zstd,并调整compression.zstd.level=1,观察生产者和消费者端的CPU与网络带宽变化,如果网络带宽是瓶颈,zstd收益会更明显。
冷存储与归档场景:宁可慢,也要小

对于三个月前的日志、历史备份、数据仓库离线报表,推荐使用xz或gzip -9,这类数据写入一次后很少读取,压缩时间不是问题,但要注意,一旦需要恢复数据,解压会非常慢,所以归档时建议保留一个“索引文件”或者按块压缩,避免全量解压。
实操思路:对大文件进行分块压缩,比如每1GB一个压缩块,解压时可以只解压需要的块,而不是整个文件,这在运维实践中能大大缩短恢复时间。
常见问题:压缩算法选择的几个纠结点
数据压缩算法和存储成本之间如何平衡?
答案:平衡点在于你的数据访问频率,高频读数据,用LZ4或snappy,虽然存储费高一点,但查询快,用户体验好;低频读数据,用zstd高等级或xz,存储费降低,读慢一点可以接受,最理想的是自动化分层,让数据根据访问时间自动迁移到不同压缩策略的存储层。
无损压缩和有损压缩怎么分?数据能用有损吗?
答案:无损压缩是完整还原原始数据,适用于数据库、日志、代码等任何二进制或文本数据,有损压缩只适用于图片、视频、音频等感知型数据,对于业务数据,绝不能用有损压缩,哪怕一个bit错误都可能导致计费异常或分析错误,即使是日志,也建议用无损算法,除非你能接受丢失部分无关紧要的字段。
压缩率越高的算法是不是一定越好?
答案:不一定,高压缩率通常意味着更长的压缩时间和解压时间,以xz为例,压缩率确实高于gzip,但压缩速度慢好几倍,解压也慢,如果数据每天都在产生,压缩速度跟不上,就会形成积压,真正的“好”是让你的CPU、存储、网络这三项总成本最低,而不是单看某一项指标,用公式说:总成本 = 存储成本 + 计算成本(压缩+解压) + 网络传输成本,算总账,才是性价比。
回到开头的结论:选择数据压缩算法,本质是选择你愿意为存储省那些钱,并为之付出多少计算代价。 先分析数据特征和访问模式,再跑一跑实际测试,用数据说话,而不是跟着别人的默认配置走,zstd通常是那个“万金油”选项,但它不是万能的,冷储存用xz,热管道用LZ4,这建议永远不过时。
