4、日志压缩工具实战:gzip压缩、bzip2压缩、zstd压缩、压缩脚本编写
日志压缩这件事,说实话,我刚开始做运维那会儿根本没当回事。觉得不就是把文件变小嘛,有啥技术含量?直到有一次,线上一个服务疯狂打日志,直接把磁盘写满了,整个集群差点挂了。从那以后,我对压缩工具的选择就格外上心。
今天咱们就聊聊三个主流压缩工具:gzip、bzip2 和 zstd。我会结合实战经验,告诉你什么时候该用谁,怎么用最划算。
4.1 gzip:最通用的老大哥
gzip 应该是大家最熟悉的压缩工具了。Linux 系统基本都自带,兼容性没得说。我个人习惯用它来压缩那些需要长期归档的日志。
基本用法很简单:
# 压缩单个文件
gzip access.log
# 解压缩
gunzip access.log.gz
# 保留原文件压缩
gzip -c access.log > access.log.gz
# 查看压缩率
gzip -l access.log.gz
这里有个坑,我踩过好几次:gzip 默认会删除原文件。如果你只是想压缩一份副本,记得加 -c 参数。
4.2 bzip2:压缩率之王,但慢
bzip2 的压缩率比 gzip 高不少,但代价是速度慢。我记得有一次压一个 10GB 的日志文件,gzip 用了 2 分钟,bzip2 跑了将近 15 分钟。不过压缩后的文件确实小了一圈。
# 压缩
bzip2 error.log
# 解压缩
bunzip2 error.log.bz2
# 保留原文件
bzip2 -k error.log
# 指定压缩级别(1-9,默认9)
bzip2 -9 error.log
你想想看,什么场景下会用 bzip2?我个人建议:那些需要长期保存、不常访问的冷数据。比如一年前的审计日志,用 bzip2 压一下能省不少存储空间。
4.3 zstd:后起之秀,又快又小
zstd 是 Facebook 开源的压缩算法,这几年在日志领域越来越流行。说实话,我第一次用 zstd 的时候挺震惊的——压缩速度和 gzip 差不多,但压缩率能接近 bzip2。
# 压缩
zstd app.log
# 解压缩
unzstd app.log.zst
# 指定压缩级别(1-19,默认3)
zstd -3 app.log
# 使用多线程(需要编译时支持)
zstd -T4 app.log
为什么会这样?因为 zstd 的算法设计更现代,它可以根据数据特征动态调整策略。我个人现在新上的日志系统,基本都优先考虑 zstd。
| 工具 | 压缩率 | 压缩速度 | 解压速度 | 适用场景 |
|---|---|---|---|---|
| gzip | 中等(约 15%) | 快 | 快 | 日常日志轮转 |
| bzip2 | 高(约 10%) | 慢 | 中等 | 冷数据归档 |
| zstd | 高(约 11%) | 快 | 快 | 实时压缩、传输 |
4.4 压缩脚本编写实战
光会用命令还不够,咱们得写个脚本把压缩自动化。下面这个脚本是我在项目中实际用过的,经过多次迭代,比较靠谱。
#!/bin/bash
# 日志压缩脚本 - 支持多种压缩算法
# 用法: ./compress_logs.sh /var/log/app
LOG_DIR="$1"
COMPRESS_TOOL="${2:-gzip}" # 默认用 gzip
RETENTION_DAYS="${3:-7}" # 保留最近 7 天的日志
# 检查目录是否存在
if [ ! -d "$LOG_DIR" ]; then
echo "错误:目录 $LOG_DIR 不存在"
exit 1
fi
# 根据压缩工具选择命令
case "$COMPRESS_TOOL" in
gzip)
CMD="gzip"
EXT=".gz"
;;
bzip2)
CMD="bzip2"
EXT=".bz2"
;;
zstd)
CMD="zstd"
EXT=".zst"
;;
*)
echo "不支持的压缩工具: $COMPRESS_TOOL"
exit 1
;;
esac
# 查找需要压缩的日志文件
find "$LOG_DIR" -name "*.log" -type f | while read -r logfile; do
# 检查文件是否在保留期内
file_date=$(stat -c %Y "$logfile")
current_date=$(date +%s)
age_days=$(( (current_date - file_date) / 86400 ))
if [ "$age_days" -gt "$RETENTION_DAYS" ]; then
echo "压缩: $logfile"
$CMD "$logfile"
if [ $? -eq 0 ]; then
echo "成功: ${logfile}${EXT}"
else
echo "失败: $logfile"
fi
fi
done
echo "压缩完成!"
这个脚本有几个设计点我觉得挺实用:
- 支持三种压缩工具:通过参数切换,不用改脚本
- 保留期控制:最近几天的日志不压缩,方便排查问题
- 错误处理:压缩失败不会影响其他文件
gzip -9 最高压缩级别。结果日志量大的时候,CPU 被打满,影响了业务。后来改成默认级别,速度提升 3 倍,压缩率只差了 2%。所以别盲目追求最高压缩率。
4.5 如何选择?我的建议
说了这么多,到底该用哪个?我根据实际经验给个参考:
- 日常日志轮转:用 gzip。兼容性好,速度够快,压缩率也能接受。
- 远程传输日志:用 zstd。压缩率高、速度快,能节省带宽和时间。
- 长期冷数据归档:用 bzip2。虽然慢,但存储成本能省不少。
- 实时流式压缩:用 zstd。它的流式压缩性能最好,延迟低。
嗯,压缩工具的选择没有绝对的对错,关键看你的场景。我建议你拿自己的日志数据跑一遍测试,看看哪个最适合你。毕竟实践出真知嘛。