Zstandard

Zstandard,简称 zstd,是一种快速无损压缩算法,目标是在 zlib 级别提供实时压缩,并具有更好的压缩率。它由非常快速的熵编码阶段提供支持,该阶段由 Huff0 和 FSE 库提供。

Zstandard 的格式是稳定的,并在 RFC8878 中进行了文档说明。已经有多个独立的实现可用。此存储库代表参考实现,以开源双 BSDGPLv2 许可的 C 库,以及生成和解码 .zst.gz.xz.lz4 文件的命令行实用程序的形式提供。如果您的项目需要其他编程语言,请在 Zstandard 首页上找到已知的端口和绑定列表。

开发分支状态

Build Status Build status Build status Fuzzing Status

基准测试

作为参考,我们在配备 Core i7-9700K CPU @ 4.9GHz 并运行 Ubuntu 24.04 (Linux 6.8.0-53-generic) 的桌面上测试和比较了几种快速压缩算法,使用的工具是由 @inikep 编写的开源内存基准测试工具 lzbench,使用 gcc 14.2.0 编译,并在 Silesia 压缩语料库上进行测试。

压缩器名称 比率 压缩速度 解压缩速度
zstd 1.5.7 -1 2.896 510 MB/s 1550 MB/s
zlib 1.3.1 -1 2.743 105 MB/s 390 MB/s
brotli 1.1.0 -0 2.702 400 MB/s 425 MB/s
zstd 1.5.7 --fast=1 2.439 545 MB/s 1850 MB/s
zstd 1.5.7 --fast=3 2.241 635 MB/s 1980 MB/s
quicklz 1.5.0 -1 2.238 520 MB/s 750 MB/s
lzo1x 2.10 -1 2.106 650 MB/s 780 MB/s
lz4 1.10.0 2.101 675 MB/s 3850 MB/s
snappy 1.2.1 2.089 520 MB/s 1500 MB/s
lzf 3.6 -1 2.077 410 MB/s 820 MB/s

负压缩级别(使用 --fast=# 指定)以牺牲压缩率为代价,提供更快的压缩和解压缩速度。

Zstd 还可以通过牺牲压缩速度来提供更强的压缩率。速度与压缩率的权衡可以通过小幅度增量来配置。解压缩速度保持不变,并且在所有设置下大致相同,这是大多数 LZ 压缩算法(如 zlib 或 lzma)共有的属性。

以下测试在运行 Linux Debian (Linux version 4.14.0-3-amd64) 的服务器上进行,该服务器配备 Core i7-6700K CPU @ 4.0GHz,使用的工具是由 @inikep 编写的开源内存基准测试工具 lzbench,使用 gcc 7.3.0 编译,并在 Silesia 压缩语料库上进行测试。

压缩速度与压缩率 解压缩速度
Compression Speed vs Ratio Decompression Speed

一些其他算法可以以较慢的速度产生更高的压缩率,这些算法不在图表范围内。要查看包含慢速模式的更大图片,请点击此链接

小数据压缩的案例

之前的图表提供了适用于典型文件和流场景(几 MB)的结果。小数据有不同的视角。

要压缩的数据量越小,压缩就越困难。这个问题对于所有压缩算法都是常见的,原因是压缩算法会从过去的数据中学习如何压缩未来的数据。但在新数据集的开头,没有“过去”可以作为基础。

为了解决这种情况,Zstd 提供了训练模式,该模式可用于为选定类型的数据调整算法。训练 Zstandard 是通过向其提供一些样本(每个样本一个文件)来实现的。此训练的结果存储在一个名为“字典”的文件中,该文件必须在压缩和解压缩之前加载。使用此字典,小数据可实现的压缩率会大大提高。

以下示例使用 github-users 样本集,该样本集是从 github 公共 API 创建的。它由大约 1 万条记录组成,每条记录约 1KB。

压缩率 压缩速度 解压缩速度
Compression Ratio Compression Speed Decompression Speed

在提供更快的压缩和解压缩速度的同时,实现了这些压缩增益。

如果一小类数据样本中存在某种相关性,则训练有效。字典越针对特定数据,效率就越高(没有通用字典)。因此,为每种类型的数据部署一个字典将提供最大的好处。字典增益主要在最初的几 KB 中有效。然后,压缩算法将逐渐使用先前解码的内容来更好地压缩文件的其余部分。

字典压缩方法

  1. 创建字典

    zstd --train FullPathToTrainingSet/* -o dictionaryName

  2. 使用字典压缩

    zstd -D dictionaryName FILE

  3. 使用字典解压缩

    zstd -D dictionaryName --decompress FILE.zst

构建说明

make 是此项目的官方维护构建系统。所有其他构建系统都是“兼容的”和第三方维护的,它们可能在高级选项中存在细微差异。如果您的系统允许,请优先使用 make 来构建 zstdlibzstd

Makefile

如果您的系统与标准 make(或 gmake)兼容,则在根目录中调用 make 将在根目录中生成 zstd cli。它还将在 lib/ 中创建 libzstd

其他可用选项包括

Makefile 遵循 GNU 标准 Makefile 约定,允许分阶段安装、标准标志、目录变量和命令变量。

对于高级用例,控制二进制生成的专用编译标志记录在 lib/README.md(用于 libzstd 库)和 programs/README.md(用于 zstd CLI)中。

cmake

cmake 项目生成器在 build/cmake 中提供。它可以生成 Makefiles 或其他构建脚本来创建 zstd 二进制文件以及 libzstd 动态和静态库。

默认情况下,CMAKE_BUILD_TYPE 设置为 Release

支持胖(Universal2)输出

可以通过使用 CMake 的 Universal2 支持来构建和安装 zstd,使其同时支持 Apple Silicon (M1/M2) 和 Intel。要执行胖/Universal2 构建和安装,请使用以下命令

cmake -B build-cmake-debug -S build/cmake -G Ninja -DCMAKE_OSX_ARCHITECTURES="x86_64;x86_64h;arm64"
cd build-cmake-debug
ninja
sudo ninja install

Meson

Meson 项目在 build/meson 中提供。按照该目录中的构建说明进行操作。

您还可以查看 .travis.yml 文件,了解有关如何使用 Meson 构建此项目的示例。

请注意,默认构建类型为 release

VCPKG

您可以构建和安装 zstd vcpkg 依赖项管理器

git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install zstd

vcpkg 中的 zstd 端口由 Microsoft 团队成员和社区贡献者保持最新。如果版本已过期,请在 vcpkg 存储库上创建问题或拉取请求

Conan

您可以使用 Conan 安装 zstd 的预构建二进制文件或从源代码构建它。使用以下命令

conan install --requires="zstd/[*]" --build=missing

zstd Conan 配方由 Conan 维护人员和社区贡献者保持最新。如果版本已过期,请在 ConanCenterIndex 存储库上创建问题或拉取请求

Visual Studio (Windows)

进入 build 目录,您将找到其他可能性

Buck

您可以通过从 repo 根目录执行:buck build programs:zstd 来通过 buck 构建 zstd 二进制文件。输出二进制文件将在 buck-out/gen/programs/ 中。

Bazel

通过使用 Bazel Central Repository 上托管的模块,您可以轻松地将 zstd 集成到您的 Bazel 项目中。

测试

您可以通过运行 make check 来运行快速本地冒烟测试。如果无法使用 make,请从 src/tests 目录执行 playTest.sh 脚本。测试脚本需要两个环境变量 $ZSTD_BIN$DATAGEN_BIN 来定位 zstddatagen 二进制文件。有关 CI 测试的信息,请参阅 TESTING.md

状态

Zstandard 目前已部署在 Facebook 和许多其他大型云基础设施中。它持续运行,以压缩多种格式和用例的大量数据。Zstandard 被认为是生产环境安全的。

许可证

Zstandard 在 BSDGPLv2 下获得双重许可。

贡献

dev 分支是在到达 release 之前合并所有贡献的分支。如果您计划提出补丁,请提交到 dev 分支或其自己的功能分支。不允许直接提交到 release。有关更多信息,请阅读 CONTRIBUTING