JSONL 压缩:gzip vs zstd vs Brotli

JSONL 文件压缩实用指南。比较压缩比、速度基准,了解何时为数据管道、云存储和 Web 分发使用 gzip、zstd 或 Brotli。

最后更新:2026年2月

为什么要压缩 JSONL 文件?

JSONL 文件增长很快。一天的应用日志就能产生数 GB 的行分隔 JSON,机器学习数据集通常达到数十 GB。不压缩的话,您需要支付更多存储费用,传输时间更长,I/O 成为数据管道的瓶颈。在大规模场景下,压缩不是可选的 —— 它是高效处理 JSONL 数据的基础部分。

好消息是 JSONL 的压缩效果非常好。因为 JSON 是重复的文本,具有循环出现的键、分隔符和结构模式,压缩算法可以利用这种冗余实现 5 到 15 倍的大小缩减。挑战在于为您的用例选择正确的算法:gzip 提供通用兼容性,zstd 提供最佳的速度与压缩比权衡,Brotli 为静态资源实现最高压缩率。本指南通过真实基准测试、可用代码示例和清晰的建议对三者进行了比较。

压缩算法概述

三种算法主导了 JSONL 压缩领域。每种使用不同的策略,针对不同的场景进行了优化。了解它们的权衡有助于您为特定工作负载做出正确选择。

gzip (DEFLATE)

通用

通用标准。gzip 自 1992 年以来一直存在,到处都支持 —— 每种编程语言、每种操作系统、每个云提供商和每个浏览器。它使用结合了 LZ77 和 Huffman 编码的 DEFLATE 算法。虽然不是最快或最高效的,但其普遍性使它成为兼容性最重要时的安全默认选择。

Zstandard (zstd)

推荐

由 Facebook 于 2016 年开发,zstd 是数据压缩的现代主力。它的压缩和解压速度明显快于 gzip,同时实现相似或更好的压缩比。Zstd 还支持字典压缩,这对于每行共享相同键结构的 JSONL 文件特别有效。它是数据管道和实时处理的最佳选择。

Brotli

最高压缩比

由 Google 创建,Brotli 在三者中实现最高的压缩比,特别是在最大压缩级别下。它使用 LZ77、Huffman 编码和内置的常见 Web 内容静态字典的组合。Brotli 擅长为 HTTP 传输和静态存储压缩 JSONL,但其在高级别下的压缩速度明显慢于 gzip 或 zstd。

正面对比

下表总结了压缩 JSONL 文件时最重要指标上 gzip、zstd 和 Brotli 之间的关键差异。这些是默认设置下的一般特征;实际性能因数据和压缩级别而异。

指标gzipzstdBrotli
压缩比良好 (5-8x)很好 (6-10x)优秀 (7-12x)
压缩速度中等慢到中等
解压速度中等非常快
CPU 占用中等低到中等高(最大级别时)
浏览器支持所有浏览器Chrome 123+、Firefox 126+所有现代浏览器
流式支持是(原生)是(原生)有限

基准测试结果:100 MB JSONL 文件

为了给出具体数据,以下是压缩一个 100 MB JSONL 文件的基准测试结果。该文件包含应用日志记录,每条记录有 12 个字段,包括时间戳、日志级别、消息字符串和嵌套元数据对象。测试在配备 32 GB RAM 和 NVMe 存储的 AMD Ryzen 7 上运行。

算法与级别压缩大小压缩比压缩时间解压时间
gzip(级别 6)14.2 MB7.0x2.8s0.9s
gzip(级别 9)13.1 MB7.6x8.4s0.9s
zstd(级别 3)12.8 MB7.8x0.6s0.3s
zstd(级别 1)15.1 MB6.6x0.3s0.3s
Brotli(级别 6)11.5 MB8.7x3.2s0.5s
Brotli(级别 11)9.8 MB10.2x42.1s0.4s

基准测试代表典型的 JSONL 日志数据。结果因字段基数、值熵和记录结构而异。具有高度重复键和低熵值(如日志级别或状态码)的文件压缩效果优于具有唯一高熵字符串的文件。

压缩代码示例

以下是在 Python、Node.js 和命令行中压缩和解压 JSONL 文件的实用示例。每个示例展示了如何使用所有三种算法。

Python 内置 gzip 支持。对于 zstd 和 Brotli,安装 pyzstd 和 brotli 包。三者都遵循相同的模式:打开压缩文件句柄,然后通过它读写 JSONL 行。

Python: gzip、zstd 与 Brotli
import gzip
import json
# === gzip (built-in) ===
# Write compressed JSONL
with gzip.open('data.jsonl.gz', 'wt', encoding='utf-8') as f:
for record in records:
f.write(json.dumps(record, ensure_ascii=False) + '\n')
# Read compressed JSONL
with gzip.open('data.jsonl.gz', 'rt', encoding='utf-8') as f:
for line in f:
record = json.loads(line)
# === zstd (pip install pyzstd) ===
import pyzstd
# Write compressed JSONL
with pyzstd.open('data.jsonl.zst', 'wt', encoding='utf-8') as f:
for record in records:
f.write(json.dumps(record, ensure_ascii=False) + '\n')
# Read compressed JSONL
with pyzstd.open('data.jsonl.zst', 'rt', encoding='utf-8') as f:
for line in f:
record = json.loads(line)
# === Brotli (pip install brotli) ===
import brotli
# Compress an entire JSONL file
with open('data.jsonl', 'rb') as f:
raw = f.read()
compressed = brotli.compress(raw, quality=6)
with open('data.jsonl.br', 'wb') as f:
f.write(compressed)
# Decompress
with open('data.jsonl.br', 'rb') as f:
raw = brotli.decompress(f.read())
for line in raw.decode('utf-8').splitlines():
record = json.loads(line)

Node.js 通过 zlib 模块内置支持 gzip 和 Brotli。对于 zstd,使用 @aspect-build/zstd 或 fzstd npm 包。基于流的 API 非常适合处理大型 JSONL 文件而无需将其完全加载到内存中。

Node.js: zlib gzip 与 Brotli
import { createReadStream, createWriteStream } from 'fs';
import { createGzip, createGunzip, createBrotliCompress,
createBrotliDecompress } from 'zlib';
import { createInterface } from 'readline';
import { pipeline } from 'stream/promises';
// === gzip compress ===
await pipeline(
createReadStream('data.jsonl'),
createGzip({ level: 6 }),
createWriteStream('data.jsonl.gz')
);
// === gzip decompress & parse ===
const gunzip = createGunzip();
const rl = createInterface({
input: createReadStream('data.jsonl.gz').pipe(gunzip),
});
for await (const line of rl) {
if (line.trim()) {
const record = JSON.parse(line);
// process record
}
}
// === Brotli compress ===
await pipeline(
createReadStream('data.jsonl'),
createBrotliCompress(),
createWriteStream('data.jsonl.br')
);
// === Brotli decompress & parse ===
const br = createBrotliDecompress();
const rl2 = createInterface({
input: createReadStream('data.jsonl.br').pipe(br),
});
for await (const line of rl2) {
if (line.trim()) {
const record = JSON.parse(line);
}
}

命令行工具是压缩 JSONL 文件最快的方式。gzip 预装在所有 Unix 系统上。通过包管理器安装 zstd 和 brotli 即可使用其他两种算法。

命令行:gzip、zstd 与 Brotli
# === gzip ===
# Compress (keeps original by default with -k)
gzip -k data.jsonl # -> data.jsonl.gz
gzip -9 -k data.jsonl # max compression
# Decompress
gzip -d data.jsonl.gz
# or: gunzip data.jsonl.gz
# === zstd ===
# Install: brew install zstd / apt install zstd
zstd data.jsonl # -> data.jsonl.zst
zstd -3 data.jsonl # level 3 (default)
zstd --fast data.jsonl # fastest compression
# Decompress
zstd -d data.jsonl.zst
# or: unzstd data.jsonl.zst
# === Brotli ===
# Install: brew install brotli / apt install brotli
brotli data.jsonl # -> data.jsonl.br
brotli -q 6 data.jsonl # quality 6
brotli -q 11 data.jsonl # max compression
# Decompress
brotli -d data.jsonl.br
# === Piping with jq ===
# Compress filtered JSONL
cat data.jsonl | jq -c 'select(.level == "error")' | gzip > errors.jsonl.gz
# Decompress and count lines
zstd -dc data.jsonl.zst | wc -l

云存储压缩策略

在云对象存储中存储 JSONL 文件时,压缩既能减少存储成本又能缩短传输时间。大多数云提供商通过其 CDN 层支持 gzip 和 Brotli 的透明解压,但上传和存储策略有所不同。

使用正确的 Content-Encoding 头将压缩的 JSONL 上传到 S3。S3 存储压缩字节,CloudFront 可以通过自动解压来提供服务。对于数据湖工作负载,AWS Athena 和 Spark 原生读取 gzip 和 zstd 压缩的 JSONL。

AWS S3 压缩
guide-jsonl-compression.jsonlCompression.cloudStorage.s3.code

Google Cloud Storage 支持 gzip 透明编码。当您使用 Content-Encoding: gzip 头上传 gzip 压缩的对象时,GCS 可以在客户端发送 Accept-Encoding: gzip 时自动提供解压版本。对于 BigQuery 导入,可直接使用 gzip 压缩的 JSONL。

Google Cloud Storage 压缩
from google.cloud import storage
import gzip
import json
client = storage.Client()
bucket = client.bucket('my-data-bucket')
# Upload gzip-compressed JSONL
def upload_compressed(records, blob_name):
blob = bucket.blob(f{blob_name}.jsonl.gz)
blob.content_encoding = 'gzip'
blob.content_type = 'application/x-ndjson'
data = '\n'.join(
json.dumps(r, ensure_ascii=False) for r in records
).encode('utf-8')
blob.upload_from_string(
gzip.compress(data),
content_type='application/x-ndjson',
)
# BigQuery: load compressed JSONL directly
# bq load --source_format=NEWLINE_DELIMITED_JSON \
# my_dataset.my_table gs://bucket/data.jsonl.gz schema.json

最佳实践:何时使用哪种算法

没有单一的最佳压缩算法。正确的选择取决于您是优先考虑存储大小、处理速度、兼容性,还是三者的平衡。以下是常见 JSONL 用例的明确建议。

归档与冷存储

使用 Brotli(质量 9-11)或 zstd(级别 19+)获得最大压缩。

归档时压缩时间不那么重要。压缩一次,很少解压。Brotli 质量 11 可以在 JSONL 数据上实现 10 倍以上的压缩,显著降低长期存储成本。

实时数据管道

使用 zstd(级别 1-3)获得最佳的速度与压缩比权衡。

在流式管道(Kafka、Kinesis、Flink)中,压缩和解压速度直接影响吞吐量和延迟。Zstd 级别 1 的压缩速度比 gzip 快,同时实现更好的压缩比。其字典模式非常适合具有固定 Schema 的 JSONL。

Web 分发与 API

静态文件使用 Brotli,gzip 作为兼容性回退。

所有现代浏览器通过 Accept-Encoding: br 支持 Brotli。Cloudflare 和 CloudFront 等 CDN 可以自动使用 Brotli 压缩。对较老客户端使用 gzip 回退。zstd 的浏览器支持正在增长但尚未普及。

ETL 与批处理

使用 gzip 获得最大兼容性,或使用 zstd 获得更好的性能。

大多数数据工具(Spark、Athena、BigQuery、pandas)原生支持 gzip。Zstd 支持正在快速改善。如果您的工具链支持 zstd,优先使用它可获得 3-5 倍更快的压缩和相当的压缩比。

试试我们的免费 JSONL 工具

上传前压缩您的 JSONL 文件,或使用我们的免费在线工具验证和转换它们。无需安装。

在线处理 JSONL 文件

直接在浏览器中查看、验证和转换最大 1GB 的 JSONL 文件。无需上传,100% 私密。

常见问题

JSONL 压缩 — gzip vs zstd vs brotli(基准测试) | jsonl.co