[JSON] JSON Lines(JSONL / NDJSON)
0 序
-
研究契机
- JSON Line 这种格式在过去工作项目(某车联网云平台的车端日志文件数据)的过程中实际一直有在使用,当时一直觉得这压根不符合标准的JSON规范。
- 这不,最近又偶然看到它出现在了某个开源项目中。我恍惚觉得,这可能可能本身就是一种基于JSON标准规范的新场景下的扩展规范。
-
JSONLine 是啥?
- 面向流式日志与大数据的「一行一 JSON」文本格式 —— JSON Lines(JSONL / NDJSON)
- 本文讨论对象为 JSON-NL,其标准指代为 JSON Lines(JSONL,又称 Newline-Delimited JSON / NDJSON)
- 即:每个文本行包含一个独立合法 JSON 值的文本序列格式。
- 官方站点: https://jsonlines.org
1 概述
产品介绍
定位:JSON Lines 是一种轻量文本序列格式,把「【换行符】」当作【记录分隔符】,使每个文本行都是一个完整的、独立的 JSON 值。
- 诞生的背景与原因:标准 JSON 把整份数据包进单个数组或对象,解析时必须一次性读入内存;对于日志、实时流、超大数据集,这种「整块加载」既不灵活又浪费内存。业界需要一个可逐条处理、可流式追加、可被 unix 管道直接消费的 JSON 变体,JSON Lines 应运而生。
- 解决的核心问题:
- 无需把整个文件载入【内存】,可一行一行读取和处理;
- 天然适合追加写入(append),日志/采集端可持续追加新记录;
- 与
grep、jq、sed等 unix 文本工具及 shell 管道完美配合; - 进程间可作为消息流传递,一条记录即一个消息。
- URLs:
- 官网 / 规范文档:https://jsonlines.org/
- 官方示例:https://jsonlines.org/examples/
- 官方校验器:https://jsonlines.org/validator/
- NDJSON(社区同名规范,GitHub):
- 相关 RFC:JSON Text Sequences(RFC 7464):
发展历程
- 2013:JSON Lines 格式被非正式规范化(jsonlines.org 提出三条核心规则);同期 GitHub 社区发布 NDJSON 1.0 规范草案。
- 2014(10 月):NDJSON 规范更新至 1.0.0;大数据处理工具开始采用该格式。
- 2015:机器学习数据集领域广泛使用(逐样本训练数据天然契合)。
- 2016:主流大数据处理框架(Hadoop / Spark / Flink 生态)普遍支持。
- 至今:成为流式 JSON 与大体积数据集的标准存储/传输形态之一。
- 标准化状态:JSON Lines 本身尚未成为正式 RFC 标准(MIME 类型
application/jsonl也未标准化,官方在 https://jsonlines.org 上公开征集帮助);与之平行的JSON Text Sequences(RFC 7464)与 NDJSON 社区规范则是更正式的兄弟规范。
主要功能(必读)
- 逐行 JSON 解析:每条记录独立解析,坏记录可被局部跳过,不影响其余数据。
- 流式追加:支持在文件末尾持续追加新记录,适合日志与采集管道。
- 流式消费:与
jq、grep、shell 管道、gzip/bzip2压缩流组合使用。 - 进程间消息传递:一条记录即一个消息,可作轻量 IPC / 流协议载荷。
- 跨工具通用:几乎所有语言的标准库或第三方库都支持(Python
jsonlines、orjsonl、Node@portable/jsonl、json-nd等)。
核心优势(必读)
- 内存友好:逐条处理,不要求整文件驻留内存,可处理远超内存的大文件。
- 与 unix 生态无缝协作:
cat file.jsonl | jq -c '.' | grep ...式管道直接可用。 - 天然可追加 / 可切割:按行分片、按行拼接、断点续传都非常自然。
- 容错性好:单行损坏不影响其他行,便于日志场景下的局部恢复。
- 编码明确:强制 UTF-8,避免多编码歧义(官方要求禁止 BOM)。
主要短板(必读)
- 非独立标准化:核心规范由社区维护,尚未成为正式 RFC;MIME 类型未定。
- 无内建模式 / 类型约束:与标准 JSON 一样,无 schema,字段错误需应用层校验。
- 行内大小受限:单条记录过大会使「按行处理」优势减弱,且不适合包含未转义换行的自由文本。
- 可读性一般:压缩后单行很长,人眼阅读不如格式化 JSON 直观。
- 重复元数据冗余:【无列头概念】,同构记录的公共字段会逐行重复(相对 CSV / Parquet 冗余)。
局限性(必读)
- 不适合「单个超大对象」:若数据本身是一个巨大对象而非多条记录,JSON Lines 无意义。
- 不适合结构化列存查询:OLAP 列存、强压缩、谓词下推场景应选用 Parquet / ORC 等列式格式。
- 弱 schema 治理:跨行一致性靠约定,缺少类型校验、枚举约束等能力。
- 网络传输无分帧标准:作为消息流时,行分隔仍需在应用层约定(RFC 7464 的 RS 分隔可用于分帧,但未普及)。
适用场景(必读)
- 日志采集与存储:应用日志、访问日志逐行追加。
- 大数据 / 流式 ETL:Spark / Flink / Kafka 等逐条消费与清洗。
- 机器学习数据集:一条样本一行(LLM 微调数据、评测数据等常用
.jsonl)。 - 增量同步与备份:按行追加,断点续传。
- 进程间 / 服务间消息流:轻量流式协议载荷。
- 数据导出:数据库 / 数据仓库导出为可逐行重放的
dump。
同类竞品(必读)
| 竞品 | 类型 | 与 JSON Lines 的关系 / 差异 |
|---|---|---|
| NDJSON | 换行分隔 JSON 文本 | 与 JSONL 几乎等价,命名差异;NDJSON 有独立 1.0 规范(application/x-ndjson)。 |
| JSON Text Sequences (RFC 7464) | 换行分隔 JSON 文本 | 用 RS(Record Separator, U+001E)作分帧符、可跨行,比 JSONL 更利于含换行文本的流。 |
| CSV / TSV | 表格文本 | 更紧凑、有列头,但只有字符串类型、无标准转义,复杂嵌套表达差。 |
| Parquet / ORC | 列式二进制 | 高压缩、列存查询高效,但不可流式逐行追加、人类不可读。 |
| 标准 JSON(数组) | 单文档 | 整体加载、需一次解析完整,适合小数据与 API 载荷。 |
发展趋势(必读)
- 开源社区活跃趋势:规范本身由社区驱动(jsonlines.org、NDJSON spec),生态库持续更新(如 Python
orjsonl于 2026-10 仍发布新版本、Node@portable/jsonl于 2026-10 发布);因是「格式而非代码库」,Star/Fork 主要体现在各语言的实现库,而非单一仓库。 - 采用面持续扩大:机器学习(LLM 微调 / 评测数据集)、日志管道、流式数据湖落盘等场景中,
.jsonl已成为事实标准之一。 - 总结:JSON Lines 凭借「逐行、流式、unix 友好」的特性,在日志、大数据与 AI 数据集场景中已成为长期稳定的事实标准格式,规范化与生态库仍在稳步演进。
2 工作原理与架构
概念术语
- 记录(Record / Value):一个独立、完整的 JSON 值(对象或数组最常见,也可为 string/number/boolean/null)。
- 换行符(Line Terminator):记录之间的唯一分隔符,规范要求为
\n;\r\n因 JSON 解析时忽略周边空白而被兼容支持。 - 流式(Streaming):按行顺序逐条读取 / 解析,不整体加载。
- 追加(Append):在文件末尾新增一行记录。
- NDJSON:与 JSONL 等价的新行分隔 JSON 的别名。
- JSON Text Sequences(RFC 7464):用 RS(U+001E)分帧、允许跨行的 JSON 文本流规范。
- 记录分隔符(RS, U+001E):RFC 7464 使用的控制字符分帧符。
架构与运行原理
格式定义(三条核心规则,来自 jsonlines.org)
- UTF-8 编码:文件必须为 UTF-8;同 JSON 标准,禁止包含 BOM(U+FEFF)。
- 每行是一个合法 JSON 值:最常见为对象或数组,但任何 JSON 值均允许(
null合法,空行不合法)。 - 行终止符为
\n:\r\n亦被兼容;文件末尾的最后一个 JSON 值后是否追加换行符推荐但不强制(追加换行便于生成与拼接,若存在则须是文件最后一个字节)。
处理模型
flowchart LR
SRC["JSON Lines 文件 / 流<br/>.jsonl / .jsonl.gz / 网络流"] --> SPLIT["按 '\\n' 切分逐行"]
SPLIT --> PARSE["逐行 JSON 解析<br/>(每行一个独立值)"]
PARSE --> PROC["逐条处理<br/>(过滤/转换/聚合)"]
PROC --> OUT["输出 / 追加写回<br/>gzip·管道·存储"]
- 读取侧:按换行切分 → 逐行调用 JSON 解析器 → 每条独立处理(单行损坏只影响该行)。
- 写入侧:每完成一个对象即序列化为单行文本 + 换行 → 追加写回。
- 压缩:通常用
gzip/bzip2整体压缩(.jsonl.gz),解压后仍是逐行结构。 - 消息流:一条记录即一个消息,适合进程间 / 服务间传递。
与标准 JSON 的结构差异
flowchart LR
subgraph A["标准 JSON(单文档)"]
A1["{ ... } 或 [ ... ] 整体包裹<br/>一次性整体解析"]
end
subgraph B["JSON Lines(多记录)"]
B1["第1行: {...}"]
B2["第2行: {...}"]
B3["第3行: {...}"]
end
A -.->|"展开数组"| B
B -.->|"折叠为数组"| A
3 使用指南
安装部署(Windows / Linux)
JSON Lines 是「格式」而非单个软件,使用方式取决于你所用的语言 / 工具。以下为常见处理库与命令行工具的安装方式。
命令行工具
- jq(JSON 处理,天然支持逐行):
- Linux:
sudo apt install jq(Debian/Ubuntu)或sudo yum install jq(RHEL/CentOS)。 - Windows:
winget install jq或从 https://stedolan.github.io/jq/ 下载 exe 并加入 PATH。
- Linux:
- Python
jsonlines库:pip install jsonlines
- Node
@portable/jsonl:npm install @portable/jsonl
关键操作
1. 读取 JSONL(Python,逐行处理)
import jsonlines
with jsonlines.open("data.jsonl") as reader:
for obj in reader: # 每条记录一个 dict
print(obj.get("id"))
2. 写入 JSONL(追加 / 流式写入)
import jsonlines
with jsonlines.open("out.jsonl", mode="w") as writer:
writer.write({"id": 1, "name": "a"})
writer.write({"id": 2, "name": "b"})
3. 命令行管道处理(unix 友好)
# 查看前5条记录的关键字段
head -n 5 access.jsonl | jq -c '.user, .path'
# 按条件过滤
cat data.jsonl | jq -c 'select(.level > 3)'
# gzip 压缩 / 解压
gzip -k data.jsonl # 生成 data.jsonl.gz
zcat data.jsonl.gz | head -n 3 # 解压查看
4. 校验文件是否为合法 JSONL:使用官方校验器 https://jsonlines.org/validator/,或逐行 jq -c . file.jsonl > /dev/null。
Z FAQ for JSON-Lines
Q: JSONL、NDJSON、JSON-NL 是同一个东西吗?
- 是。三者都指「每行一个合法 JSON 值、以换行分隔」的文本格式。JSONL(JSON Lines)与 NDJSON(Newline-Delimited JSON)是同一格式的两个常用别名,JSON-NL 是它的中文 / 通用简称。细微差异仅在规范署名与扩展名(
.jsonlvs.ndjson)、建议 MIME(application/jsonlvsapplication/x-ndjson)。
Q: JSONL 与标准 JSON 数组比,为什么要用 JSONL?
- 标准 JSON 数组必须整体解析、整体入内存,不适合日志、超大文件、增量追加与流式消费;JSONL 可以逐行处理、按行追加、单行容错,天然契合流式与大数据场景。代价是缺少数组的整体结构约束与格式化可读性。
Q: JSONL 与 RFC 7464(JSON Text Sequences)有何区别?
- JSONL 以换行符
\n作记录分隔;RFC 7464 以记录分隔符 RS(U+001E) 作分帧符并允许记录跨行(记录内可含换行)。若单条记录内可能出现未转义换行,RFC 7464 更稳妥;纯 JSONL 中换行必须转义为\n。
Q: JSONB 是「JSON 的二进制格式」吗?和 JSONL 冲突吗?
- 是同一家族的存储形态,但不冲突、不互斥:JSONB 是 PostgreSQL / MySQL / DWS 等关系库内把 JSON 文本解析为优化二进制以支持索引与快速查询的数据类型;JSONL 是文件 / 流层面的逐行文本格式。两者可结合使用(如把 JSONL 数据批量导入库中的 JSONB 字段)。
Q: HOCON 和 JSON 能互相转换吗?
- 能。HOCON 是 JSON 的超集,任何合法 JSON 都是合法 HOCON;HOCON 也可(在无注释、无 include / 替换的纯字面情况下)序列化为合法 JSON。但 HOCON 面向人类可读配置(支持注释、
${}替换、include),这些特性无法 1:1 映射回 JSON。
Q: JSON-RPC 是格式还是协议?必须走 HTTP 吗?
- JSON-RPC 是基于 JSON 的 RPC 协议,定义请求/响应对象与错误码,是应用层消息规范;它与传输无关,可通过 HTTP、WebSocket、Unix 套接字、进程内等任意通道承载,不一定走 HTTP。
Y 推荐文献
- JSON Lines
- RFC 7464 - JavaScript Object Notation (JSON) Text Sequences - datatracker.ietf.org
- PostgreSQL JSON 类型文档(json / jsonb) - postgresql.org
- HOCON 规范(Lightbend / Typesafe Config) - github.com
- JSON-RPC 2.0 规范 - jsonrpc.org
X 参考文献
- JSON Lines - jsonlines.org
- JSON Lines Examples - jsonlines.org
- NDJSON 定义与规范说明 - ndjson.rest
- RFC 7464 - JSON Text Sequences - IETF
- PostgreSQL JSON 类型 - PostgreSQL
- HOCON 配置格式 - EMQX 官方文档
- JSON-RPC 2.0 Specification - jsonrpc.org
- JSON - json.org
- ECMA-404 - The JSON Data Interchange Format - ECMA International
- JSON vs. NDJSON - Software Engineer's Notes
本文作者:
千千寰宇
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!

浙公网安备 33010602011771号