3. 常见日志压缩算法一览
日志压缩这个坑,说起来可大可小。我早年维护的一个日志采集系统,每天几十 TB 的原始日志塞进来,存储成本高得离谱。那时候第一反应就是上压缩,结果没选对算法,把 CPU 直接打满了……你想想看,日志压缩不是单纯的「压得越小越好」——得看场景。
这一节咱们就把常用的六种算法过一遍:gzip、bzip2、lz4、zstd、snappy、lzma。我会把每种算法的核心特点、适合的场景,以及我在项目中踩过的坑都摊开来讲。
3.1 Gzip
Gzip 用的是 Deflate 算法,算是压缩界的「老黄牛」了。压缩率中等,速度也中等,兼容性极好——几乎所有系统都自带 gzip 命令。我最早接触日志压缩就是用的 gzip,因为简单:gzip access.log 就完事了。
个人建议:如果你的日志归档后很少再读,或者需要跨平台共享,gzip 是最稳妥的。但实时压缩写入?我劝你慎重——它单线程处理,高并发场景容易成为瓶颈。
3.2 Bzip2
Bzip2 用了 Burrows-Wheeler 变换,压缩率比 gzip 高不少,代价是速度慢得让人着急。我记得有一次给一个历史日志数据做冷备份,压了一整天……压缩后只有 gzip 的 70%,但解压也慢,检索时痛苦无比。这玩意儿现在基本只出现在「极致压缩」的冷数据场景,线上实时日志千万别碰。
3.3 Lz4
Lz4 是极端速度派的代表。压缩和解压速度都极快,但压缩率低(通常只有 2~3 倍)。我在做实时日志采集管道的时候,用的是 Lz4 做在线压缩,然后加一层 Gzip 做长期归档。这样既保证了写入吞吐,又控制了存储成本。
典型的「快存慢算」策略:热数据用 Lz4 留 7 天,冷数据切为 Gzip 存 90 天。
3.4 Zstd
Zstd(Zstandard)算是后起之秀,Facebook 出品。压缩率可以比肩 gzip,但速度是 gzip 的好几倍,而且支持多个压缩级别(1~22)。我习惯在日志轮转时用 Zstd -3,又快又省空间。它的字典训练功能也很强——如果你有一批结构相似的日志,预训练一个字典,压缩率还能再提升 30%。
不过要注意:Zstd 的 19 级以后内存消耗暴涨(几百 MB),服务器内存紧张时不要无脑开最高级。
3.5 Snappy
Snappy 是 Google 开发的,追求「压缩速度」和「解压速度」的平衡,压缩率比 Lz4 还差一点。它在很多大数据引擎(Hadoop、Cassandra)里作为默认压缩。我做过测试,Snappy 的压缩速度大约是 Gzip 的 5 倍,但解压速度是 Gzip 的 2 倍——对 CPU 友好。它跟 Lz4 的选择其实挺微妙的:如果你的日志行特别短,Snappy 略优;行较长时 Lz4 更稳。
3.6 Lzma
Lzma(7-Zip 的算法)是压缩率的王者,但速度也是倒数第一。我曾经用 Lzma 压一个 10 GB 的日志文件,结果跑了两个小时,压成 1.2 GB,压缩率 8 倍多。不过解压也慢,而且内存占用高(默认 64 MB 字典)。适合一年以上的冷归档,平时别用。
算法横向对比
| 算法 | 压缩率(同级别) | 压缩速度 | 解压速度 | 内存占用(默认) | 我的推荐场景 |
|---|---|---|---|---|---|
| gzip | 中等(~3x) | 中 | 中 | 低(~256KB) | 通用归档、跨平台 |
| bzip2 | 较高(~4x) | 慢 | 慢 | 中(~8MB) | 冷数据、极少访问 |
| lz4 | 低(~2x) | 极快 | 极快 | 极低(~1KB) | 实时写入、热日志 |
| zstd | 高(可调,~3.5x) | 快 | 快 | 中(~8MB 高级别更高) | 实时+归档平衡 |
| snappy | 极低(~1.5x) | 极快 | 极快 | 极低(~1KB) | 大数据管道、短行日志 |
| lzma | 极高(~5x+) | 极慢 | 慢 | 高(~64MB+) | 年度冷归档 |
避坑提醒:我曾经在生产环境看到有人把 tar -cjf(bzip2)用在每天轮转的日志上,结果服务器 CPU 飙到 100% 持续半小时,差点造成日志丢失。当时我就给团队立了规矩:压缩算法必须和访问频率绑定,不能一刀切。
看完这个分布图,你应该能感受到每个算法的位置。说白了,选哪个取决于你的日志处在「读写管道」的哪个环节。我个人习惯按这个优先级拍:
- 在线写入 + 实时查询:Lz4 或 Snappy,CPU 扛得住,IO 快。
- 近线归档 + 偶尔查询:Zstd -3 ~ -5,压缩率和速度都过得去。
- 离线冷存储 + 几乎不查:Lzma 或 bzip2,能省一半存储费。
嗯,这一章就先到这里。记住:没有最好的算法,只有最适合你日志 pipeline 的那个。