消息大小要过四道关
一条消息能否成功写入并读出,取决于四层限制是否都放得下:生产端 max.request.size、broker 的 message.max.bytes、主题级 max.message.bytes,以及消费端 max.partition.fetch.bytes 与 fetch.max.bytes。任何一层偏小,要么生产端直接报 RecordTooLargeException,要么消息已经写进去但消费端拉不动,卡在同一个位移上不肯前进。
基本信息
| 生产端 | max.request.size,默认 1MB |
|---|---|
| Broker 级 | message.max.bytes,默认约 1MB |
| 主题级 | max.message.bytes,默认继承 broker 配置 |
| 消费端 | max.partition.fetch.bytes 默认 1MB,fetch.max.bytes 默认 50MB |
典型使用场景
- 上游写入超大记录报错:先定位是哪一层拒绝的
- 消费长时间不前进:怀疑某条消息超过消费端拉取上限
- 大报文改造前的评估:确认四层限制各需放宽多少
- 主题级特殊放宽:只放大个别主题的上限,不影响集群整体
- 故障复盘:区分是单条消息过大还是批量请求超限
调整与核对
调整与核对
# 主题级放宽到 5MB(5242880 字节)
kafka-configs.sh --bootstrap-server localhost:9092 \
--entity-type topics --entity-name orders \
--alter --add-config max.message.bytes=5242880
# 生产端与消费端需要同步调整,任何一层偏小都会失败
# producer: max.request.size=5242880
# consumer: max.partition.fetch.bytes=5242880
# 查看该主题当前的覆盖配置,确认改动已生效
kafka-configs.sh --bootstrap-server localhost:9092 \
--entity-type topics --entity-name orders --describe四层限制对照
| 位置 | 参数 | 默认参考值 | 过小的后果 |
|---|---|---|---|
| 生产者 | max.request.size | 1MB | 发送时即报 RecordTooLargeException |
| Broker | message.max.bytes | 约 1MB | 服务端拒收,生产端收到错误 |
| 主题 | max.message.bytes | 继承 Broker 配置 | 仅该主题被拒,其他主题正常 |
| 消费者 | max.partition.fetch.bytes | 1MB | 消息已写入但拉不到,消费停滞 |
大消息会同时放大内存占用与端到端延迟,单条达到数 MB 时优先考虑拆分消息、提高压缩率,或把大对象放对象存储、消息里只传引用,而不是一味提高上限。
排查「生产成功但消费不动」时,先算一下消息实际字节数是否超过消费端 max.partition.fetch.bytes,再考虑其他原因,比上来就翻日志更快。
批量请求也会超限
除了单条消息,生产端一次请求里的整批消息也会受 max.request.size 约束:批量攒得多、单条又偏大时,整批字节数先撞上线,报错信息与单条超限很像,容易被误判。压缩能缓解这一点——压缩针对整个批次生效,重复度高的 JSON 消息压缩后往往能显著缩小体积,但要注意 broker 侧是按压缩后的批次做大小校验,生产端与消费端的解压内存开销另算。批量发送的延迟与批量大小本身也是权衡:批量越大吞吐越好,单条消息的端到端延迟也越长。