当前位置: 移动技术网 > IT编程>开发语言>Java > Zstd 压缩性能分析

Zstd 压缩性能分析

2020年07月31日  | 移动技术网IT编程  | 我要评论
About ZstdZstd,全称 Zstandard,是 Facebook 于 2016 年开源的新无损压缩算法。与 zlib、lz4、xz 等当前流行的压缩算法不同,Zstd 寻求一种压缩性能与压缩率通吃的方案,而实际上它也确实做到了。在由官方所列出的表格中,可以看到,Zstd 不仅具备优秀的压缩性能,在压缩率上也有非常亮眼的表现。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RXOO1Z8l-1596090419061)(https://engineering.fb

About Zstd

Zstd,全称 Zstandard,是 Facebook 于 2016 年开源的新无损压缩算法。与 zlib、lz4、xz 等当前流行的压缩算法不同,Zstd 寻求一种压缩性能与压缩率通吃的方案,而实际上它也确实做到了。在由官方所列出的表格中,可以看到,Zstd 不仅具备优秀的压缩性能,在压缩率上也有非常亮眼的表现。

image

综合来说,Zstd 具有以下特性:

  • 在压缩性能和压缩率上均有很突出的表现
  • 支持以训练方式生成字典文件,可显著提高对小数据包的压缩率

About Zstd-jni

Zstd-jni,顾名思义,是基于 Zstd 本地库实现的 Java 调用接口。它支持通过 Java 语言实现 Zstd 的压缩与解压缩。

在 Zstd-jni 的三方包中,主要实现了以下功能:

  • 提供静态的压缩与解压缩方法
  • 支持压缩数据的流式传输
  • 支持字典文件的训练与添加

Code Example

下面示例代码将展示 Zstd-jni 的压缩、解压、字典训练等功能:

package com.panda.zstd;

import com.github.luben.zstd.Zstd;
import com.github.luben.zstd.ZstdDictCompress;
import com.github.luben.zstd.ZstdDictDecompress;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * zstd 示例
 *
 * @author panda
 * @date 2020/7/29
 */
public class ZstdDemo {

    private static final Logger LOGGER = LoggerFactory.getLogger(ZstdDemo.class);

    // 训练文件
    private static final String TRAIN_FILE = "C:\\Users\\admin\\Desktop\\train\\train-10000.txt";

    // 待压缩文件
    private static final String COMPRESS_FILE = "C:\\Users\\admin\\Desktop\\train\\test.txt";

    // 压缩等级,以时间换空间
    private static final Integer LEVEL = 10;

    // 解压时字节数组的最大值
    private static final Integer MAX_SIZE = 1000000;

    private static ZstdDictCompress compressDict;

    private static ZstdDictDecompress decompressDict;

    public static void main(String[] args) throws IOException {
        String s = FileUtils.readFileToString(new File(COMPRESS_FILE), StandardCharsets.UTF_8);
        byte[] bytes = s.getBytes(StandardCharsets.UTF_8);

        train();
        compress(bytes);
    }

    public static void train() throws IOException {
        // 初始化词典对象
        String dictContent = FileUtils.readFileToString(new File(TRAIN_FILE), StandardCharsets.UTF_8);
        byte[] dictBytes = dictContent.getBytes(StandardCharsets.UTF_8);
        compressDict = new ZstdDictCompress(dictBytes, LEVEL);
        decompressDict = new ZstdDictDecompress(dictBytes);
    }

    public static void compress(byte[] bytes) {
        LOGGER.info("raw data length: {}", bytes.length);

        // 压缩数据
        long compressBeginTime = System.currentTimeMillis();
        byte[] compressed = Zstd.compress(bytes, compressDict);
        long compressEndTime = System.currentTimeMillis();
        LOGGER.info("compress spend time: {}", compressEndTime - compressBeginTime);
        LOGGER.info("compressed data length: {}", compressed.length);

        // 解压数据
        long decompressBeginTime = System.currentTimeMillis();
        // 第 3 个参数不能小于解压后的字节数组的大小
        byte[] decompressed = Zstd.decompress(compressed, decompressDict, MAX_SIZE);
        long decompressEndTime = System.currentTimeMillis();
        LOGGER.info("decompress spend time: {}", decompressEndTime - decompressBeginTime);
        LOGGER.info("decompressed data length: {}", decompressed.length);
    }
}

Performance Testing

当前,我们具有以下需求场景:使用 Flume 收集与发送日志,在接收到日志后,对日志对象的 body 进行压缩,再传递给下游,以减少网络传输的开销。据此可以了解到,实际上我们是希望通过 Zstd 实现小文件的压缩与解压

在上面我们提到过,Zstd 支持以训练方式生成字典文件,可提高对小数据包的压缩率。显然,这个特性非常适合我们的需求场景。因此,我们决定将字典作为自变量,测试在不同样本集的字典下,Zstd 的压缩性能与压缩率。

通过测验,我们希望能解决以下疑问:

  • Zstd 是否能满足小文件的压缩与解压需求
  • Zstd 的压缩性能如何,是否会造成数据延时
  • 字典的引入能否提高压缩率,如何选择正确的样本集

首先,我们准备如下 4 份字典文件:

  • train-A:表示含有 5000 条样本日志的字典文件
  • train-B:表示含有 10000 条样本日志的字典文件
  • train-C:表示含有 15000 条样本日志的字典文件
  • train-D:表示含有 20000 条样本日志的字典文件

然后,我们输入 10000 行日志数据,对这些字典分别进行性能测验,测验的指标包含压缩率、压缩时间与解压时间。

测验后,对各指标取平均值,计算结果如下表所示:

dict sample num compress ratio(%) compress time(ms) decompress time(ms)
none 0 54.08 0.03 0.10
train-A 5000 81.85 0.15 0.10
train-B 10000 82.20 0.15 0.09
train-C 15000 82.06 0.15 0.09
train-D 20000 81.07 0.15 0.08

注:ratio = 文件原大小 - 压缩后的大小 / 文件原大小。

结合测验过程及测验结果,我们得出以下结论:

  • zstd 可以满足小文件的压缩与解压需求,经压缩-解压后,数据保持无损状态
  • zstd 的压缩性能非常优秀,平均压缩与解压消耗时间甚至未达到毫秒级别,不会造成数据延时
  • 字典引入可以显著提高压缩率,但会在一定程度上影响压缩性能
  • 字典样本集并非越大越好,合适的样本集更能提高压缩率,根据测验结果,建议样本集数量维持在 10000 左右

Reference

本文地址:https://blog.csdn.net/magicpenta/article/details/107689459

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网