大数据-57 Kafka 高级特性 Producer 消息发送流程与核心配置详解

点一下关注吧!!!非常感谢!!持续更新!!!

🚀 AI篇持续更新中!(长期更新)

AI炼丹日志-30-新发布【1T 万亿】参数量大模型!Kimi‑K2开源大模型解读与实践,持续打造实用AI工具指南!📐🤖

💻 Java篇正式开启!(300篇)

目前2025年07月28日更新到: Java-83 深入浅出 MySQL 连接、线程、查询缓存与优化器详解 MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈! 大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解

章节内容

上节我们完成了如下的内容:

  • Java添加POM依赖
  • Java操作Kafka的API、SpringBoot
  • 实现对Kafka消息发送和消息消费

基本流程

Kafka Producer 消息发送流程详解

Producer初始化阶段

  • 在创建KafkaProducer实例时,会同步初始化以下核心组件:
    • 创建并启动Sender线程,该线程负责实际的消息发送,被设置为守护线程(daemon thread)
    • 初始化RecordAccumulator消息缓冲区,默认大小32MB
    • 加载配置的拦截器链(Interceptor)、序列化器(Serializer)和分区器(Partitioner)

消息发送流程

  • 当调用send()方法时,实际是异步处理流程: a. 拦截处理 :消息首先通过配置的ProducerInterceptor链进行处理(可用于添加消息头、监控等) 示例:可添加traceId等分布式追踪信息

    b. 序列化阶段:分别对消息key和value进行序列化

    • 默认使用ByteArraySerializer,也可配置为StringSerializer等

    c. 分区路由:通过Partitioner确定目标分区

    • 默认使用RoundRobin或Key哈希策略
    • 自定义分区器需实现Partitioner接口

消息缓冲与批次发送

  • 消息会被暂存到RecordAccumulator缓冲区
  • 触发批次发送的条件(满足任一即触发):
  • 每个分区对应独立的批次队列

网络传输与Broker处理

  • Sender线程将批次消息通过网络发送到目标分区Leader副本
  • Broker端处理流程:
    • 写入Leader副本的PageCache
    • 同步到ISR副本集
    • 根据acks配置等待副本同步确认

异常处理机制

  • 重试条件:
    • retries参数>0(默认Integer.MAX_VALUE)
    • 错误类型可重试(如网络异常、NOT_LEADER等)
  • 重试策略:
    • 具备backoff退避机制(通过retry.backoff.ms配置)
    • 避免无效重试(如消息过大等不可恢复错误)

响应处理

  • 同步模式:通过Future.get()阻塞等待响应
  • 异步模式:通过Callback接口处理响应
  • 响应元数据包含:
    • 主题、分区信息
    • 消息offset
    • 时间戳等信息

关键配置参数

参数 默认值 说明
batch.size 16384 批次大小(字节)
linger.ms 0 批次等待时间
buffer.memory 33554432 缓冲区总大小
max.block.ms 60000 缓冲区满时阻塞时间
retries 2147483647 最大重试次数
acks 1 消息确认机制

Broker配置

这里是Broker的常见配置:

bootstrap.servers

生产者客户端与broker集群建立初始链接需要Broker的地址列表,由该初始连接发现Kafka集群中其他的所有Broker,该地址列表不需要写全部的Kafka集群地址,但也不要只写一个防止宕机不可用。

key.serializer

实现了 org.apache.kafka.common.serialization.Serializer 的key序列化类

value.serializer

实现了 org.apache.kafka.common.serialization.Serializer的value序列化类

acks

该项控制着已发消息的持久性。

  • acks=0,生产者不等待Broker的任何消息确认。
  • acks=1,Leader将记录写到它本地的地址,就相应客户端的消息,而不等待Follower的副本的确认。
  • acks=all,Leader等待所有有同步副本消息的确认,保证了只要有一个同步副本存在,消息就不会丢失。
  • acks=-1,等价于 acks=all 默认值为1

compression.type

生产者生成数据的压缩格式,默认是none(无压缩)。 可选:

  • none
  • gzip
  • snappy
  • lz4

默认是none

Broker配置补充

额外的配置还有下图的这些内容:

retry.backoff.ms

在向一个指定的主题分区重发消息的时候,控制重试之间的等待时间间隔。这个参数非常重要,它可以避免在遇到临时性故障时过于频繁地重试,从而减轻系统负担。

  • 参数作用:当生产者发送消息失败时,会在指定的时间间隔后自动重试
  • 工作方式:采用指数退避策略,每次重试的间隔会逐渐增加
  • 使用场景:在网络不稳定或broker负载较高时特别有用
  • 实际示例:假设设置为100ms,第一次重试等待100ms,第二次可能等待200ms,第三次可能等待400ms

long型 默认 100

retries

retries参数配置生产者发送消息时的重试次数。

  • 核心功能:当消息发送出现可重试错误时(如网络问题、leader选举等),系统会自动重新发送消息
  • 注意事项
    • 如果同时需要保证消息的有序性,必须设置MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION=1
    • 重试可能导致消息重复,消费者端需要做好幂等处理
  • 推荐值:生产环境通常设置为3-5次
  • 错误类型:只对可恢复的异常进行重试(如NetworkException、NotLeaderForPartitionException等)

request.timeout.ms

配置客户端等待请求响应的最长时间。

  • 关键作用:控制生产者等待broker响应的时间阈值
  • 配置建议
  • 超时处理
    • 超时后会触发重试机制(如果配置了retries>0)
    • 连续超时达到重试次数上限后会抛出TimeoutException
  • 影响因素:受网络状况、broker负载、消息大小等因素影响

int型 默认 30000

interceptor.classes

配置生产者拦截器链,用于在消息发送前进行预处理。

  • 执行时机:在消息序列化之前,即将发送到Kafka集群时执行
  • 主要用途
    • 消息内容审计和修改
    • 发送统计和监控
    • 附加元数据信息
  • 实现要求
    • 必须实现org.apache.kafka.clients.producer.ProducerInterceptor接口
    • 需要定义onSend()和onAcknowledgement()方法
  • 配置方式:通过Map[String, Object] configs中的List集合配置多个拦截器
  • 执行顺序:按照配置顺序依次执行
  • 典型应用
    • 日志打点
    • 消息加密
    • 请求追踪

默认没有拦截器

acks

同上,不介绍了。

batch.size

当多个消息发送到同一个分区时,生产者会尝试将多个记录合并为一个批处理(batch)进行发送。这种批处理机制能显著提高客户端和服务端的处理效率,减少网络请求次数。该配置项以字节为单位控制默认批处理的大小,其具体行为和影响如下:

  1. 批处理大小限制:

    • 所有批处理的大小都小于或等于该配置值
    • 例如设置为16KB(16384)时,每个批处理最大不超过16KB
  2. 请求发送机制:

    • 发送给Broker的请求将包含多个批次
    • 每个分区对应一个批次
    • 请求中只包含当前可发送的数据批次
  3. 配置影响:

    • 过小值的影响:
      • 会限制系统的吞吐量
      • 极端情况下(设置为0)会完全关闭批处理功能
      • 示例:设置为1KB可能导致频繁的小批量请求
    • 过大值的影响:
      • 会占用较多内存资源
      • 可能导致消息延迟发送
      • 示例:设置为100MB时可能造成内存浪费
  4. 典型场景:

    • 高吞吐场景建议设置较大的值(如64KB-1MB)
    • 低延迟场景可适当减小该值(如16KB-32KB)
    • 需根据消息平均大小和分区数量进行权衡

client.id

client.id是生产者在发送请求时传递给Broker的身份标识字符串,其主要作用和特性包括:

  1. 核心功能:

    • 用于在Broker的请求日志中追踪消息来源
    • 帮助识别是哪个应用程序发送了特定消息
    • 在监控和故障排查时提供重要依据
  2. 命名规范:

    • 通常采用与业务相关的描述性字符串
    • 示例:订单服务可能使用"order-service-producer"
    • 建议包含应用名称和环境标识(如dev/prod)
  3. 实际应用:

    • 在分布式系统中识别不同生产者实例
    • 结合监控系统实现细粒度的性能监控
    • 用于配额管理和访问控制
  4. 最佳实践:

    • 保持唯一性和可读性
    • 避免使用敏感信息
    • 在微服务架构中建议采用标准命名规范

compression.type

同上,不介绍了。

send.buffer.bytes

TCP发送数据的时候用的缓冲区的大小,若设置为0,则用操作系统默认的。

buffer.memory

生产者可以用来缓存等待发送到服务器的记录的总内存字节,如果记录的发送速度超过了将记录发送到服务器的速度,则生产者将阻塞 max.block.ms 的时间,此后将引发异常。 此设置应大致对应于生产者将使用的总内存,但并非生产者使用的所有内存都用于缓冲。

connections.max.idle.ms

当连接空闲时间达到这个值,就关闭连接。 long型 默认 540000

linger.ms

生产者发送请求传输间隔会对需要发送的消息进行累积,然后作为一个批次发送,一般情况是消息的发送速度比消息积累的速度要慢。 有时候客户端需要减少请求次数,即使在负载不大的情况下。该配置设置了一个延迟,生产者消息不会立即将消息送到Broker,而是等待这么一段时间以积累消息,然后将这段消息之类的消息作为一个批次发送,该设置是批处理的另一个上限,一旦此消息达到了batch.size指定的值,消息批会立即发送,如果积累的消息字节数达不到batch.size的值,可以设置该毫秒值,等待这么长时间之后,也会发送消息批。 默认值是0

max.block.ms

控制KafkaProducer.send()和KafkaProducer.partitionFor()阻塞时长,当缓存满了或元数据不可用的时候,这些方法阻塞。在用户提供的序列化器和分区器的阻塞时间不计入。 long型值,默认60000

max.request.size

单个请求的最大字节数,该设置会限制单个请求总消息批的个数,以免单个请求发送太多的数据,服务器有自己的限制批大小的设置,与该配置可能不一样 int 型 默认 1048576

partitioner.class

实现了接口 org.apache.kafka.clients.producer.Partitioner 的分区器实现类。默认值:org.apache.kafka.clients.producer.internals.DefaultPartitioner

receive.buffer.bytes

TCP接收缓存(SO_RECVBUF),设置为01,则使用操作系统默认的值。 int型 默认32768

security.protocol

跟 Broker 通信的协议:PLAINTEXT、SSL、SASL_PLAINTEXT、ASAL_SSL String型 默认 PLAINTEXT

max.in.flight.requests.per.connection

单个连接上未确认请求的最大数量,达到这个数量,客户端阻塞。 如果该值大于1,则存在失败的请求,在重试的时候消息顺序不能保证。 int型 默认5

reconnect.backoff.max.ms

对于每个连续的连接失败,每台主机退避将成倍增加,直到达到此最大值。

reconnect.backoff.ms

尝试重连指定主机的基础等待时间,避免该主机的密集重连。

相关推荐
杨DaB1 小时前
【SpringMVC】拦截器,实现小型登录验证
java·开发语言·后端·servlet·mvc
微学AI5 小时前
时序数据库选型指南:工业大数据场景下基于Apache IoTDB技术价值与实践路径
大数据·apache·时序数据库
lingling0097 小时前
颐顿机电携手观远BI数据:以数据驱动决策,领跑先进制造智能化升级
大数据·人工智能·制造
b***25117 小时前
电池自动生产线:科技赋能下的高效制造新范式
大数据·人工智能
努力的小雨8 小时前
还在为调试提示词头疼?一个案例教你轻松上手!
后端
魔都吴所谓8 小时前
【go】语言的匿名变量如何定义与使用
开发语言·后端·golang
陈佬昔没带相机8 小时前
围观前后端对接的 TypeScript 最佳实践,我们缺什么?
前端·后端·api
Livingbody10 小时前
大模型微调数据集加载和分析
后端
Livingbody10 小时前
第一次免费使用A800显卡80GB显存微调Ernie大模型
后端
哈哈很哈哈10 小时前
Hadoop JMX 配置的完整文档
大数据·hadoop·分布式