目 录CONTENT

文章目录

💻工作经历:优化日志压缩算法

TalentQ
2025-09-04 / 0 评论 / 0 点赞 / 5 阅读 / 0 字

1 日志压缩逻辑存在严重问题

设备运行期间会产生大量日志,直接存储很容易遇到磁盘空间不足的风险,因此需要对日志文件进行压缩。

原有的压缩逻辑中,直接将整个日志文件一次性加载到内存,瞬时几百MB的内存消耗,对内存造成极大的压力,存在诸多风险:

  • 内存压力过大时,操作系统可能会触发OOM(Out of Memory)机制,直接杀死占用内存过多的进程;

  • 影响其它服务正常运行,可能导致其它服务不可用;

  • 内存占用过高会导致系统频繁进行垃圾回收,增加CPU的负载,影响整体性能;

  • 更大的日志文件,意味着更高的风险,风险不可控;

因此需要优化日志压缩算法。除了内存风险之外,同时考虑不同压缩率、不同压缩算法和算法压缩速率,优化日志压缩算法。

2 压缩逻辑优化

压缩方式根据其工作方式可以分为三种类型:

流式压缩:预先不可知文件大小,边读边压缩,低内存

块式压缩:预先分块处理,可并行

文件压缩:整体压缩,高压缩率

原先的逻辑是这里的“文件压缩”,由于日志文件并不像网络视频或音频这种流式的数据,所以更适合“块式压缩”。

对比原先的整体的“文件压缩”,“块式压缩”可以预先对文件进行分块,块大小固定(比如1MB),每次加载一块数据到内存中,避免了内存出现瞬时峰值。由于分块的大小会影响压缩速度和压缩率,还需要进一步对不同分块(如128KB、256KB...1MB、2MB...)做对比试验。

3 压缩算法对比

6种压缩算法:zstd、pzstd、brotli、lz4、gzip、pigz。

压缩算法

描述

zstd

Zstandard(Zstd)是由 Facebook 于 2015 年推出的现代无损压缩算法,专为高压缩率与高速处理而设计。它采用先进的词典压缩和熵编码技术,支持1至22级可调压缩等级,能在保持较高压缩效率的同时实现远超传统算法(如Deflate/zlib)的压缩和解压速度。

zstd 提供流式接口,适合大数据、实时传输和嵌入式场景,并已被广泛集成于操作系统、数据库、分布式存储等众多主流项目中,兼容性和扩展性极强。

pzstd

pzstd 是 zstd 的并行化实现,专为多核处理器优化。它通过将输入文件划分为多个独立数据块,并利用多线程并行进行压缩和解压,极大提升了大文件和高吞吐量场景下的处理效率。pzstd 完全兼容 zstd 的压缩格式,用户可通过命令行参数灵活指定线程数,自动适配系统资源。

其优势在于显著缩短批量数据归档、分布式备份和日志处理等任务的整体运行时间,是高性能服务器和数据中心环境的理想选择。

brotli

Brotli 是由 Google 开发的一种现代无损压缩算法,广泛用于 Web 传输(如 HTTP 内容压缩)和静态资源压缩。Brotli 结合了 LZ77 字典压缩、哈夫曼编码和二阶上下文建模技术,能够在保持高压缩率的同时,提供较快的解压速度。

它支持多级压缩率调节,尤其在高压缩等级下优于传统的 gzip。Brotli 已被主流浏览器和 Web 服务器广泛支持,是网页传输优化的主流选择,同时在静态文件归档、移动应用等场景也有应用。

lz4

LZ4 是一种极高速的无损压缩算法,专注于实现极快的压缩和解压速度,适用于对实时性和低延迟有高要求的场景。LZ4 的压缩率略低于 zlib 和 Brotli,但其解压速度在所有主流压缩算法中处于领先地位。

LZ4 被广泛用于日志系统、数据库、分布式存储(如 Hadoop、Cassandra)、内存缓存(Redis)和嵌入式设备等领域,支持流式处理和块式压缩,适合大数据和高性能计算环境。

gzip

Gzip 是基于 Deflate 算法的经典无损压缩工具,由 Jean-loup Gailly 和 Mark Adler 于 1992 年开发,至今仍是文件压缩和网络传输的标准选择。Gzip 采用 LZ77 字典压缩结合哈夫曼编码,兼容性极高,几乎所有操作系统和编程语言都原生支持。

Gzip 广泛用于 UNIX/Linux 系统的文件打包、Web 服务器的 HTTP 内容压缩、数据归档等场景,特点是压缩率适中,解压速度较快,稳定可靠。

pigz

Pigz(Parallel Implementation of Gzip)是 Gzip 的多线程并行版本,由 Mark Adler 开发。Pigz 利用多核 CPU,将输入数据分块并行压缩,大幅提升了大文件的压缩速度,但仍保持与 Gzip 完全兼容的压缩格式。

Pigz 适合服务器、数据中心及批量数据归档等高性能场景,用户可通过参数灵活指定线程数,充分利用硬件资源。它是大规模文件处理和自动化备份任务中的理想工具。

最终对100个文件近100G数据进行测试,测试指标有CPU占用、内存占用、总压缩时间、平均压缩时间、平均压缩速度,压缩速度方差、平均压缩率、压缩率方差。综合各种因素,最终选取zstd算法,绑定某个CPU核,进行生产环境中的压缩任务。

绑核指令:

taskset -c <核心编号> <COMMAND>  # 核心编号可以指定多个,用逗号分隔

4 哈夫曼编码(Huffman Coding)

详细信息参考我的另一篇博客:哈夫曼编码

哈夫曼编码(Huffman Coding)是一种无损熵编码技术,其核心思想是:出现频率越高的符号用越短的码字,频率越低的符号用越长的码字,从而在整体上使平均码长逼近信源熵的理论下限。

哈夫曼编码的核心时构建一棵哈夫曼树,具体步骤:

  1. 统计每个符号的出现频率;

  2. 将所有符号作为叶子节点,根据频率升序排列;

  3. 每次取出频率最低的两个节点,合并为一个新节点,其频率为两者之和;

  4. 将新节点差回队列,继续合并直到只剩下一个根节点;

  5. 从根节点到叶子节点,左分支记为0,右分支记为1,得到每个副奥的比特编码。

有A,B,C,D,E五个字符,出现的频率(即权值)分别为5,4,3,2,1:

0

评论区