[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 值。

发展历程

  • 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)

  1. UTF-8 编码:文件必须为 UTF-8;同 JSON 标准,禁止包含 BOM(U+FEFF)。
  2. 每行是一个合法 JSON 值:最常见为对象或数组,但任何 JSON 值均允许(null 合法,空行不合法)。
  3. 行终止符为 \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。
  • 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 是它的中文 / 通用简称。细微差异仅在规范署名与扩展名(.jsonl vs .ndjson)、建议 MIME(application/jsonl vs application/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


X 参考文献

posted @ 2026-11-02 23:50  千千寰宇  阅读(5)  评论(0)    收藏  举报