JSONL 圧縮:gzip vs zstd vs Brotli
JSONL ファイル圧縮の実践ガイド。圧縮率とスピードのベンチマークを比較し、データパイプライン、クラウドストレージ、Web 配信で gzip、zstd、Brotli をいつ使うべきかを学びます。
最終更新:2026年2月
なぜ JSONL ファイルを圧縮するのか?
JSONL ファイルは急速に大きくなります。1日分のアプリケーションログで数ギガバイトの行区切り JSON が生成されることがあり、機械学習データセットは日常的に数十ギガバイトに達します。圧縮なしでは、ストレージコストが増加し、転送に時間がかかり、I/O がデータパイプラインのボトルネックになります。大規模運用では圧縮はオプションではなく、JSONL データを効率的に扱うための基本です。
良いニュースは、JSONL は非常に良く圧縮できるということです。JSON は繰り返されるキー、デリミタ、構造パターンを含む反復的なテキストであるため、圧縮アルゴリズムはこの冗長性を活用して 5 倍から 15 倍のサイズ削減を達成できます。課題は、使用ケースに適したアルゴリズムを選ぶことです:gzip はユニバーサルな互換性を提供し、zstd は速度と圧縮率の最適なトレードオフを実現し、Brotli は静的アセットに対して最高の圧縮を達成します。このガイドでは、3つすべてを実際のベンチマーク、動作するコード例、明確な推奨事項で比較します。
圧縮アルゴリズムの概要
3つのアルゴリズムが JSONL 圧縮の分野を支配しています。それぞれ異なる戦略を使用し、異なるシナリオ向けに最適化されています。トレードオフを理解することで、特定のワークロードに適した選択ができます。
gzip (DEFLATE)
ユニバーサルユニバーサルスタンダード。gzip は 1992 年から存在し、あらゆるプログラミング言語、すべてのオペレーティングシステム、すべてのクラウドプロバイダー、すべての Web ブラウザでサポートされています。LZ77 とハフマン符号化を組み合わせた DEFLATE アルゴリズムを使用します。最速でも最効率でもありませんが、互換性が最も重要な場合の安全なデフォルトの選択です。
Zstandard (zstd)
推奨2016 年に Facebook が開発した zstd は、データ圧縮の現代的な主力です。gzip よりも大幅に高速に圧縮・解凍しながら、同等またはそれ以上の圧縮率を達成します。Zstd は辞書圧縮もサポートしており、すべての行が同じキー構造を共有する JSONL ファイルに特に強力です。データパイプラインとリアルタイム処理に最適な選択です。
Brotli
最高圧縮率Google が作成した Brotli は、特に最大圧縮レベルで3つの中で最高の圧縮率を達成します。LZ77、ハフマン符号化、一般的な Web コンテンツの組み込み静的辞書の組み合わせを使用します。Brotli は HTTP 配信と静的ストレージ用の JSONL 圧縮に優れていますが、高レベルでの圧縮速度は gzip や zstd よりも著しく遅くなります。
比較一覧
以下の表は、JSONL ファイルを圧縮する際に最も重要な指標で gzip、zstd、Brotli の主な違いをまとめています。これらはデフォルト設定での一般的な特性であり、実際のパフォーマンスはデータと圧縮レベルによって異なります。
| 指標 | gzip | zstd | Brotli |
|---|---|---|---|
| 圧縮率 | 良好(5〜8 倍) | 非常に良好(6〜10 倍) | 優秀(7〜12 倍) |
| 圧縮速度 | 中程度 | 高速 | 低速〜中程度 |
| 解凍速度 | 中程度 | 非常に高速 | 高速 |
| CPU 使用率 | 中程度 | 低〜中程度 | 高い(最大レベル時) |
| ブラウザサポート | 全ブラウザ | Chrome 123+、Firefox 126+ | 全モダンブラウザ |
| ストリーミングサポート | 対応(ネイティブ) | 対応(ネイティブ) | 限定的 |
ベンチマーク結果:100 MB JSONL ファイル
具体的な数値として、アプリケーションログレコードを含む 100 MB JSONL ファイルの圧縮ベンチマーク結果を示します。各レコードにはタイムスタンプ、ログレベル、メッセージ文字列、ネストされたメタデータオブジェクトなど 12 フィールドがあります。テストは AMD Ryzen 7、32 GB RAM、NVMe ストレージで実行されました。
| アルゴリズムとレベル | 圧縮後サイズ | 圧縮率 | 圧縮時間 | 解凍時間 |
|---|---|---|---|---|
| gzip(レベル 6) | 14.2 MB | 7.0 倍 | 2.8 秒 | 0.9 秒 |
| gzip(レベル 9) | 13.1 MB | 7.6 倍 | 8.4 秒 | 0.9 秒 |
| zstd(レベル 3) | 12.8 MB | 7.8 倍 | 0.6 秒 | 0.3 秒 |
| zstd(レベル 1) | 15.1 MB | 6.6 倍 | 0.3 秒 | 0.3 秒 |
| Brotli(レベル 6) | 11.5 MB | 8.7 倍 | 3.2 秒 | 0.5 秒 |
| Brotli(レベル 11) | 9.8 MB | 10.2 倍 | 42.1 秒 | 0.4 秒 |
ベンチマークは典型的な JSONL ログデータの代表値です。結果はフィールドのカーディナリティ、値のエントロピー、レコード構造によって異なります。高度に反復的なキーと低エントロピーの値(ログレベルやステータスコードなど)を持つファイルは、ユニークで高エントロピーな文字列を持つものよりもよく圧縮されます。
圧縮コード例
Python、Node.js、コマンドラインでの JSONL ファイルの圧縮・解凍の実践的な例を示します。各例では3つのアルゴリズムすべての使い方を紹介します。
Python には gzip のビルトインサポートがあります。zstd と Brotli には pyzstd と brotli パッケージをインストールします。3つとも同じパターンに従います:圧縮ファイルハンドルを開き、それを通じて JSONL 行を読み書きします。
import gzipimport json# === gzip (built-in) ===# Write compressed JSONLwith 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 JSONLwith 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 JSONLwith 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 JSONLwith 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 filewith 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)# Decompresswith 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 ファイルを処理するのに最適です。
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 システムにプリインストールされています。他の2つのアルゴリズムにはパッケージマネージャーで zstd と brotli をインストールします。
# === gzip ===# Compress (keeps original by default with -k)gzip -k data.jsonl # -> data.jsonl.gzgzip -9 -k data.jsonl # max compression# Decompressgzip -d data.jsonl.gz# or: gunzip data.jsonl.gz# === zstd ===# Install: brew install zstd / apt install zstdzstd data.jsonl # -> data.jsonl.zstzstd -3 data.jsonl # level 3 (default)zstd --fast data.jsonl # fastest compression# Decompresszstd -d data.jsonl.zst# or: unzstd data.jsonl.zst# === Brotli ===# Install: brew install brotli / apt install brotlibrotli data.jsonl # -> data.jsonl.brbrotli -q 6 data.jsonl # quality 6brotli -q 11 data.jsonl # max compression# Decompressbrotli -d data.jsonl.br# === Piping with jq ===# Compress filtered JSONLcat data.jsonl | jq -c 'select(.level == "error")' | gzip > errors.jsonl.gz# Decompress and count lineszstd -dc data.jsonl.zst | wc -l
クラウドストレージ圧縮戦略
クラウドオブジェクトストレージに JSONL ファイルを保存する際、圧縮によりストレージコストと転送時間の両方が削減されます。ほとんどのクラウドプロバイダーは CDN レイヤーを通じて gzip と Brotli の透過的な解凍をサポートしていますが、アップロードとストレージの戦略は異なります。
正しい Content-Encoding ヘッダー付きで圧縮 JSONL を S3 にアップロードします。S3 が圧縮バイトを格納し、CloudFront が自動解凍で配信できます。データレイクワークロードでは、AWS Athena と Spark が gzip と zstd 圧縮 JSONL をネイティブに読み取ります。
guide-jsonl-compression.jsonlCompression.cloudStorage.s3.code
Google Cloud Storage は gzip トランスコーディングをサポートしています。Content-Encoding: gzip ヘッダー付きで gzip 圧縮オブジェクトをアップロードすると、クライアントが Accept-Encoding: gzip を送信した際に GCS が自動的に解凍版を配信できます。BigQuery インポートには gzip 圧縮 JSONL を直接使用できます。
from google.cloud import storageimport gzipimport jsonclient = storage.Client()bucket = client.bucket('my-data-bucket')# Upload gzip-compressed JSONLdef 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
ベストプラクティス:どのアルゴリズムをいつ使うか
万能な最良の圧縮アルゴリズムはありません。正しい選択は、ストレージサイズ、処理速度、互換性、またはこれら3つのバランスのどれを優先するかによります。一般的な JSONL 使用ケースへの明確な推奨事項を示します。
アーカイブとコールドストレージ
最大圧縮には Brotli(品質 9-11)または zstd(レベル 19+)を使用。
アーカイブでは圧縮時間はあまり重要ではありません。一度圧縮して、まれに解凍します。Brotli は品質 11 で JSONL データに対して 10 倍以上の圧縮を達成でき、長期ストレージコストを大幅に削減します。
リアルタイムデータパイプライン
速度と圧縮率の最適なトレードオフには zstd(レベル 1-3)を使用。
ストリーミングパイプライン(Kafka、Kinesis、Flink)では、圧縮と解凍速度がスループットとレイテンシに直接影響します。Zstd はレベル 1 で gzip よりも高速に圧縮しながら、より良い圧縮率を達成します。辞書モードは固定スキーマの 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 倍高速な圧縮が可能なため、zstd を選択してください。
無料 JSONL ツールを試す
アップロード前に JSONL ファイルを圧縮したり、無料のオンラインツールで検証・変換できます。インストール不要。