两种 JSON 形态
JSON 适合做接口响应与配置文件:一个文件就是一个完整文档,结构可以嵌套。但在数据管道里,一个巨大的 JSON 数组必须整体解析完才能取到第一个元素,无法边写边读;NDJSON(也叫 JSON Lines)把每个对象单独写一行,可以逐行解析、逐行追加,写入方与读取方不需要同时在线。日志与事件落地的默认形态基本都是 NDJSON。
基本信息
| JSON | 单文档结构,适合接口响应与配置文件 |
|---|---|
| NDJSON | 按行分隔的多个 JSON 对象,适合流式与追加写 |
| 工具 | jq 处理、Spark/Flink 原生支持解析 |
| 分隔规则 | 一行一个完整对象,行内不能有裸换行 |
| 压缩方式 | 可按行压缩后整体 gzip,仍能逐块解压 |
| 常见来源 | 应用日志、埋点上报、消息落盘 |
jq 常用操作
jq 常用操作
head -1 events.ndjson | jq '.'
jq -c 'select(.level == "ERROR") | {ts, msg}' events.ndjson | head
jq -s 'length' events.ndjson # 统计行数(会把文件读进内存)
# 逐行处理,避免整文件读入内存
while IFS= read -r line; do echo "$line" | jq -r '.ts'; done < events.ndjson | head典型使用场景
- 应用日志落地:每行一条日志,追加写不需要重写整个文件
- 埋点上报:客户端批量上报时按行拼接,服务端逐行写入
- 消息落盘:从队列消费后原样写入对象存储,保留原始结构便于回溯
- 增量导入:新增文件只包含新数据,读取时按文件粒度处理
- 调试与抽查:用 jq 快速过滤与抽取字段,不必写完整程序
常见问题与处理
| 问题 | 表现 | 处理 |
|---|---|---|
| 字段缺失 | 解析报错或取到空 | 按字符串读入后显式判断 |
| 类型漂移 | 同一字段有时字符串有时数字 | 统一转换或按字符串承接 |
| 长整型 ID | 精度丢失、末位变化 | 以字符串存储 |
| 大数组文件 | 整读解析内存溢出 | 改用 NDJSON 逐行处理 |
| 嵌套过深 | 下游取字段困难 | 落地时打平常用字段 |
解析 JSON 时字段缺失与类型漂移很常见:先按字符串读入再显式转换,比直接强类型解析更稳。
用 -s(slurp)模式处理大文件会把全部内容读进内存,只适合小文件或确实需要整体聚合的场景。