订阅更新

JSON太大Avro看不懂——消息格式到底选哪个?

Kafka手册 第 11 题 约 6 分钟读完

本文目录
  1. 先说结论
  2. 三种格式对比
  3. JSON:简单但问题多
  4. Avro:大数据场景的最佳选择
  5. Schema Registry:消息格式的管理中心
  6. 实战经验:从JSON到标准化Schema的治理之路
  7. 面试高频追问
  8. 总结

先说结论

三种主流格式:JSON(灵活但大)、Avro(紧凑+Schema演进)、Protobuf(极小+强类型)。大数据场景推荐Avro,微服务场景推荐Protobuf,快速验证阶段用JSON。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

消息格式看起来是小事,但选错了代价很大。在某知名出海硬件品牌做埋点治理的时候,1000+埋点事件全是JSON格式,字段名冗长、没有Schema约束,上下游对字段含义理解不一致,数据质量问题层出不穷。后来聚合为100+标准事件后统一了Schema规范,数据质量问题减少了60%。消息格式选型直接影响存储成本、传输效率和数据治理难度。

三种格式对比

维度JSONAvroProtobuf
可读性✅ 人类可读❌ 二进制❌ 二进制
体积大(含字段名)小(Schema分离)最小(字段用编号)
Schema演进❌ 无约束✅ 原生支持✅ 原生支持
Kafka生态通用Schema Registry最佳搭档需要额外集成
学习成本零中(需要写.avsc)中(需要写.proto)
适用场景快速开发/调试大数据ETL/数仓微服务/RPC

JSON:简单但问题多

JSON是最常见的Kafka消息格式,优点是人类可读、生态广泛、上手零成本。但在生产环境有三个致命问题:

① 体积大:每条消息都带字段名。假设一个埋点事件有20个字段,字段名本身就占了消息体积的30-40%。日均12亿条消息,多出来的就是几百GB的存储和带宽开销。

② 无Schema约束:Producer写什么格式Consumer就得接什么。字段名拼错了、类型变了、加了新字段,下游不知道,解析出来是null或者直接报错。

③ 序列化/反序列化慢:JSON是文本格式,解析需要逐字符扫描,比二进制格式慢5-10倍。

// JSON消息示例(体积大,每条都带字段名)
// 一条埋点事件约500字节
{
  "event_name": "gift_send",
  "user_id": 12345678,
  "gift_type": "rose",
  "gift_count": 10,
  "receiver_id": 87654321,
  "amount": 99.00,
  "timestamp": 1705312000000,
  "device_id": "abc-123-def-456",
  "app_version": "3.2.1",
  "os": "android"
}
// 同样的数据用Avro只有约200字节(省60%)

Avro:大数据场景的最佳选择

Avro是Hadoop生态的标准序列化格式,也是Kafka Confluent生态推荐的格式。核心优势是Schema分离——Schema存在Schema Registry里,消息体只包含数据不包含字段名,体积大幅缩小。

// Avro Schema定义(.avsc文件)
{
  "type": "record",
  "name": "GiftSendEvent",
  "namespace": "com.app.events",
  "fields": [
    {"name": "event_name", "type": "string"},
    {"name": "user_id", "type": "long"},
    {"name": "gift_type", "type": "string"},
    {"name": "gift_count", "type": "int"},
    {"name": "amount", "type": "double"},
    {"name": "timestamp", "type": "long"},
    // 新增字段必须有默认值,保证向后兼容
    {"name": "os", "type": "string", "default": "unknown"}
  ]
}

Schema演进规则:新增字段必须有默认值(向后兼容);删除字段必须有默认值(向前兼容)。这样新旧Producer/Consumer可以并存,不用同时上线。

Schema Registry:消息格式的管理中心

Schema Registry是Confluent提供的Schema管理服务,配合Avro一起用:

# Schema Registry的工作流程
#
# 1. Producer发消息前,向Registry注册Schema,获得Schema ID
# 2. 消息体 = Schema ID(4字节)+ Avro二进制数据
# 3. Consumer收到消息,用Schema ID从Registry获取Schema
# 4. 用Schema反序列化数据
#
# 好处:
# ① 消息体只有数据没有字段名 → 体积小
# ② Schema变更有兼容性检查 → 不会破坏下游
# ③ 所有Schema集中管理 → 数据治理的基础

实战经验:从JSON到标准化Schema的治理之路

在某知名出海硬件品牌做埋点治理时,历史遗留的1000+埋点事件全是JSON格式,问题非常多:

① 同一个字段不同APP叫不同名字:iOS端叫user_id,Android端叫userId,后端叫uid。下游数仓每次都要做字段映射。

② 字段类型不一致:同一个amount字段,有的是数字99.00,有的是字符串'99.00',Flink解析时经常报类型转换异常。

③ 无版本控制:客户端加了新字段,后端不知道,下游更不知道。数据丢了都发现不了。

治理方案:将1000+事件聚合为100+标准事件,定义统一的Schema规范(字段命名、类型、必填/选填),通过第三方埋点管理平台做Schema校验。治理后数据质量问题减少了60%。

面试高频追问

追问一:你们生产环境用的什么格式?

在元宇宙社交公司用JSON(历史原因,快速上线阶段没引入Avro),在出海硬件品牌做治理时用的是第三方SDK的标准格式。如果从0开始设计,我会选Avro+Schema Registry,从源头保证数据质量。

追问二:Avro和Parquet什么关系?

Avro是行式序列化格式,适合消息传输和流处理;Parquet是列式存储格式,适合分析查询。一个常见的架构是:Kafka用Avro传输,落到数仓后转成Parquet存储。两者的Schema是兼容的。

总结

消息格式面试就记住一张对比表:JSON灵活但大、Avro紧凑有Schema演进、Protobuf最小适合RPC。大数据场景推荐Avro+Schema Registry。能讲出从JSON混乱到Schema标准化的治理经历和效果数字(1000+→100+,质量问题减少60%),面试官会觉得你有数据治理的实战意识。

下一篇聊Kafka集群的监控运维:哪些指标必须盯?报警怎么设?出了问题怎么快速定位?

你们Kafka消息用的什么格式?有没有因为格式问题踩过坑?评论区聊聊~

关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长

刷题进度保存在当前浏览器