JSON太大Avro看不懂——消息格式到底选哪个?
先说结论
三种主流格式:JSON(灵活但大)、Avro(紧凑+Schema演进)、Protobuf(极小+强类型)。大数据场景推荐Avro,微服务场景推荐Protobuf,快速验证阶段用JSON。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
消息格式看起来是小事,但选错了代价很大。在某知名出海硬件品牌做埋点治理的时候,1000+埋点事件全是JSON格式,字段名冗长、没有Schema约束,上下游对字段含义理解不一致,数据质量问题层出不穷。后来聚合为100+标准事件后统一了Schema规范,数据质量问题减少了60%。消息格式选型直接影响存储成本、传输效率和数据治理难度。
三种格式对比
| 维度 | JSON | Avro | Protobuf |
|---|---|---|---|
| 可读性 | ✅ 人类可读 | ❌ 二进制 | ❌ 二进制 |
| 体积 | 大(含字段名) | 小(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年大数据老兵,聊技术、聊职场、聊成长