bigywater.tech
常见报错 · 50

Kafka RecordTooLargeException:max.request.size 与 max.message.bytes 两种原文怎么区分,默认只能发 1048489 字节,压缩不能绕过客户端检查,消费端 fetch 设 1000 字节仍读到 3 MiB 消息

发送大消息报 RecordTooLargeException 时,网上的建议是同时调 max.request.size、message.max.bytes、replica.fetch.max.bytes、fetch.max.bytes……一大串。这篇用 Kafka 4.3.1 把每个限制单独测一遍:两个 RecordTooLargeException 的原文怎么区分、各自的精确边界、能不能不重启放开、压缩怎么影响、消费端到底要不要改。

1048489
默认配置下能成功发送的最大 value 字节数(客户端 max.request.size = 1048576 先拦)
3145654
topic 的 max.message.bytes 动态改成 3 MiB 后能发送的最大 value
[3145728, 100]
消费端 fetch 限制只有 1000 字节时,仍读到的两条消息的长度

默认边界

实测 · 本机执行输出
  全部默认(max.request.size=1048576):
      最大能发送的 value 长度 = 1048489 字节
      客户端拒绝时的原文:RecordTooLargeException: The message is 1048577 bytes when serialized which is larger than 1048576, which is the value of the max.request.size configuration.
  topic t1 的 max.message.bytes(服务端查询):max.message.bytes=1048588 sensitive=false synonyms={DEFAULT_CONFIG:message.max.bytes=1048588}

客户端 max.request.size 先拦,服务端 max.message.bytes 在后。

两个原文

实测 · 本机执行输出
  客户端 max.request.size=5242880,broker 与 topic 默认:
      最大能发送的 value 长度 = 1048516 字节
      服务端拒绝时的原文:RecordTooLargeException: The request included a message larger than the max message size the server will accept.

含 max.request.size 的是客户端,含 server will accept 的是服务端。

动态放开

实测 · 本机执行输出
  Completed updating config for topic t1.
  topic max.message.bytes=3145728(3 MiB),客户端 max.request.size=5242880:
      最大能发送的 value 长度 = 3145654 字节
      服务端拒绝时的原文:RecordTooLargeException: The request included a message larger than the max message size the server will accept.
  Completed updating config for topic t1.
  对照:另一个没改的 topic t2,客户端 max.request.size=5242880:
      最大能发送的 value 长度 = 1048516 字节
      服务端拒绝时的原文:RecordTooLargeException: The request included a message larger than the max message size the server will accept.

kafka-configs 改 topic 的 max.message.bytes,不重启,只影响该 topic。

压缩

实测 · 本机执行输出
  gzip + 全是字母 a,max.request.size=默认:
      最大能发送的 value 长度 = 1048489 字节
      客户端拒绝时的原文:RecordTooLargeException: The message is 1048577 bytes when serialized which is larger than 1048576, which is the value of the max.request.size configuration.
  gzip + 全是字母 a,max.request.size=8388608:
      最大能发送的 value 长度 = 8388520 字节
      客户端拒绝时的原文:RecordTooLargeException: The message is 8388609 bytes when serialized which is larger than 8388608, which is the value of the max.request.size configuration.
  不压缩 + 全是字母 a,max.request.size=8388608(对照):
      最大能发送的 value 长度 = 1048516 字节
      服务端拒绝时的原文:RecordTooLargeException: The request included a message larger than the max message size the server will accept.

客户端按压缩前检查,服务端按压缩后批大小检查。

消费端

实测 · 本机执行输出
  已发送 1 条 3145728 字节和 1 条 100 字节的消息
  max.partition.fetch.bytes = fetch.max.bytes = 1000 -> 读到的消息长度:[3145728, 100]
  max.partition.fetch.bytes = fetch.max.bytes = 1048576 -> 读到的消息长度:[3145728, 100]

fetch 限制不是硬上限,第一批大消息仍会返回。

分步演示

大消息
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64;报错文本都是真实复现时原样捕获的(命令行工具统一用 LC_ALL=C 取英文原文,路径换成 );所有服务都是本机上自己起的、只监听 127.0.0.1,不访问外网;计时用 time.perf_counter,数字每次运行会有小幅抖动。本篇用 Homebrew Kafka 4.3.1(KRaft 单节点,127.0.0.1:9580)、kafka-clients 4.3.1、OpenJDK 21.0.13;每个 topic 1 个分区;用二分查找确定每种配置下最大能成功发送的 value 长度(key 为空);随机数据代表不可压缩,全字母 a 代表高度可压缩
    • 没有验证:多 broker 集群里的 replica.fetch.max.bytes(单节点没有副本复制);broker 级 message.max.bytes 的全局修改(只测了 topic 级);其它压缩算法(只测了 gzip);librdkafka / Python 客户端对应的错误码(MSG_SIZE_TOO_LARGE);事务与幂等生产者下的行为;Kafka 其它版本的默认值
    京ICP备2026067502号-1京公网安备11010502063487号