Bootstrap

kafka-clients之ProducerConfig

在Kafka 2.4.0版本中,ProducerConfig类提供了许多配置参数,用于控制生产者行为。这些参数可以调整Kafka生产者的性能、可靠性和行为。以下是每一个参数的详细说明:

基本配置

  1. bootstrap.servers
    • 描述:Kafka集群的地址列表,用于初始化与Kafka集群的连接。
    • 默认值:无
    • 示例localhost:9092,localhost:9093
  2. client.id
    • 描述:标识生产者的ID,便于在服务端记录日志或追踪。
    • 默认值:空
    • 示例my-producer-1
  3. key.serializer
    • 描述:将消息的键序列化为字节的类,必须是org.apache.kafka.common.serialization.Serializer的实现。
    • 默认值:无
    • 示例org.apache.kafka.common.serialization.StringSerializer
  4. value.serializer
    • 描述:将消息的值序列化为字节的类,必须是org.apache.kafka.common.serialization.Serializer的实现。
    • 默认值:无
    • 示例org.apache.kafka.common.serialization.StringSerializer

分区与负载均衡

  1. partitioner.class
    • 描述:定义消息发送到Kafka主题时分区的策略,默认使用内置的分区器,也可以自定义。
    • 默认值org.apache.kafka.clients.producer.internals.DefaultPartitioner
    • 示例:自定义类如com.example.MyPartitioner
  2. acks
    • 描述:控制生产者发送消息的确认级别。
      • 0:生产者不等待服务器的响应,消息有可能丢失。
      • 1:Leader副本确认消息后返回ack。
      • all:所有副本都确认消息后返回ack,提供最高的持久性保证。
    • 默认值1
    • 示例all
  3. retries
    • 描述:发送消息失败时生产者的重试次数。
    • 默认值2147483647 (无限重试)
    • 示例5
  4. retry.backoff.ms
    • 描述:两次重试之间的时间间隔(毫秒)。
    • 默认值100
    • 示例200

性能调优

  1. batch.size
    • 描述:生产者发送给同一分区的消息批次大小,以字节为单位。达到批次大小后会立即发送消息,即使linger.ms没有达到。
    • 默认值16384(16 KB)
    • 示例32768(32 KB)
  2. linger.ms
    • 描述:生产者在发送消息之前等待的时间,以增加批量大小。即使没有达到batch.size,生产者也会在达到linger.ms后发送消息。
    • 默认值0
    • 示例5
  3. buffer.memory
    • 描述:生产者用于缓冲消息的内存总量(字节)。
    • 默认值33554432(32 MB)
    • 示例67108864(64 MB)
  4. compression.type
    • 描述:消息的压缩类型。
      • none:不压缩。
      • gzip:使用Gzip压缩。
      • snappy:使用Snappy压缩。
      • lz4:使用LZ4压缩。
      • zstd:Kafka 2.1.0 引入的Zstandard压缩。
    • 默认值none
    • 示例gzip
  5. max.in.flight.requests.per.connection
    • 描述:在单个连接上生产者可以发送但尚未确认的最大请求数。较低的值可以减少重试时消息的顺序错误。
    • 默认值5
    • 示例1

可靠性与错误处理

  1. enable.idempotence
    • 描述:是否启用幂等性。启用后,Kafka保证每条消息只会写入一次,从而避免重复消息。
    • 默认值false
    • 示例true
  2. transactional.id
    • 描述:如果需要使用事务,则必须设置该参数,用于唯一标识一个事务性生产者。
    • 默认值:空
    • 示例my-transactional-producer
  3. delivery.timeout.ms
    • 描述:消息发送超时时间,包含重试时间。超时后消息将被丢弃。
    • 默认值120000(2分钟)
    • 示例300000(5分钟)
    • 注意该配置必须符合下面的要求,否责会抛出配置异常:delivery.timeout.ms should be equal to or larger than linger.ms + request.timeout.ms
Caused by: org.apache.kafka.common.config.ConfigException: delivery.timeout.ms should be equal to or larger than linger.ms + request.timeout.ms
	at org.apache.kafka.clients.producer.KafkaProducer.configureDeliveryTimeout(KafkaProducer.java:501)
	at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:392)
	... 3 more
  1. request.timeout.ms
    • 描述:生产者等待服务器响应的最大时间,超时后重试。
    • 默认值30000(30秒)
    • 示例60000(1分钟)
  2. max.block.ms
    • 描述:在缓冲区已满的情况下,生产者阻塞的最大时间。超过该时间将抛出异常。
    • 默认值60000(1分钟)
    • 示例300000(5分钟)

其他配置

  1. max.request.size
    • 描述:生产者发送的单个请求的最大大小,单位为字节。
    • 默认值1048576(1 MB)
    • 示例2097152(2 MB)
  2. connections.max.idle.ms
    • 描述:生产者的空闲连接关闭时间。
    • 默认值540000(9分钟)
    • 示例300000(5分钟)
  3. send.buffer.bytes
    • 描述:TCP发送缓冲区大小,单位为字节。如果设置为-1,则使用操作系统默认设置。
    • 默认值131072(128 KB)
    • 示例65536(64 KB)
  4. receive.buffer.bytes
    • 描述:TCP接收缓冲区大小,单位为字节。如果设置为-1,则使用操作系统默认设置。
    • 默认值32768(32 KB)
    • 示例65536(64 KB)

安全配置

  1. security.protocol
    • 描述:Kafka客户端与Broker之间通信的协议。
      • PLAINTEXT:不加密。
      • SSL:SSL加密。
      • SASL_PLAINTEXT:使用SASL认证但不加密。
      • SASL_SSL:使用SASL认证并加密。
    • 默认值PLAINTEXT
    • 示例SSL
  2. ssl.keystore.location
    • 描述:SSL密钥库的文件路径,用于客户端认证。
    • 默认值:空
    • 示例/path/to/keystore.jks
  3. ssl.truststore.location
    • 描述:SSL信任库的文件路径,用于验证Broker的SSL证书。
    • 默认值:空
    • 示例/path/to/truststore.jks
  4. sasl.mechanism
    • 描述:SASL身份验证机制。
      • GSSAPI:Kerberos。
      • PLAIN:用户名/密码认证。
      • SCRAM-SHA-256SCRAM-SHA-512:更安全的用户名/密码认证。
    • 默认值GSSAPI
    • 示例PLAIN

这些参数能够帮助配置Kafka生产者的各个方面,从基本的连接配置到性能优化、安全设置等,确保生产者能够根据应用的需求高效、安全地发送消息。

消息丢弃场景

极端情况下,59秒时消息阻塞获取到资源了,进入缓冲区。但是一直没能发送成功,假设重试次数为无限大。那么这条消息会在2分钟后丢弃

即默认配置下:大约 3 分钟后会导致消息丢失。下面是详细的原因分析。

详细分析
  1. **max.block.ms = 59 秒**
    • 假设在第 59 秒时,send() 操作成功地获取到缓冲区资源,并将消息放入缓冲区,从而避免 max.block.ms 的超时触发。
    • 由于已经成功进入缓冲区,消息的后续发送过程不再受 max.block.ms 影响,而是转向 delivery.timeout.ms 的控制。
  2. **delivery.timeout.ms = 2 分钟**
    • 在消息进入缓冲区后,生产者会开始尝试将其发送到 Kafka 集群。
    • 假设网络异常或集群不可用,生产者会反复重试发送该消息。即使重试次数无限大,delivery.timeout.ms 限制了整个发送过程的最大时间。
    • 因此,在消息进入缓冲区的 2 分钟后,即大约第 3 分钟(59 秒 + 2 分钟)时,delivery.timeout.ms 超时将会触发,导致消息被丢弃,并向回调抛出 TimeoutException 或相关异常。

指数回退配置案例

相关配置
  • **reconnect.backoff.ms**:初始等待时间,默认值为50毫秒。
  • **reconnect.backoff.max.ms**:等待时间的最大值,默认值为1000毫秒(1秒)。
指数退避公式

Kafka客户端使用指数退避策略,但不会将延迟时间翻倍。相反,它会增加一个固定值的时间,使其随着重试次数线性上升。可以使用公式:

wait_time=min⁡(reconnect.backoff.ms×(attempt+1),reconnect.backoff.max.ms)

其中:

  • attempt 是当前的重试次数,从0开始。
逐步退避的计算过程

以下是每次重试时的等待时间,直到达到最大值1000ms为止。

  1. 第1次重试(attempt = 0):50 ms × (0 + 1) = 50 ms
  2. 第2次重试(attempt = 1):50 ms × (1 + 1) = 100 ms
  3. 第3次重试(attempt = 2):50 ms × (2 + 1) = 150 ms
  4. 第4次重试(attempt = 3):50 ms × (3 + 1) = 200 ms
  5. 第5次重试(attempt = 4):50 ms × (4 + 1) = 250 ms
  6. 第6次重试(attempt = 5):50 ms × (5 + 1) = 300 ms
  7. 第20次重试(attempt = 19):50 ms × (19 + 1) = 1000 ms(已达最大值)

从第20次重试开始,等待时间将保持在1000毫秒,不再增长。

说明

这种递增方式可有效避免高频率重试引起的资源消耗,同时通过指数方式尽量缩短恢复时间。在高并发、网络不稳定或Kafka服务偶尔中断的情况下,合理配置这两个参数可以显著改善系统的恢复性。

;