“acks”配置是否适用于 KafkaProducer 客户端的“sender”线程?

问题描述 投票:0回答:1

我有几个关于 KafkaProducer 客户端的异步性质的问题,官方文档没有回答这些问题。

背景:

  • 我正在开发一个项目,需要将一些数据记录到 kafka 主题中。我需要确保主线程上的延迟最小,同时在逻辑中添加这个额外的发布步骤。
  • 在 KafkaProducer 的现有配置中,我们没有明确提及 acks 值,在阅读文档后,我了解到它默认设置为 all
  • 这引起了一个问题,其中要求将 acks 配置设置为 0,以便调用
    send()
    的应用程序线程不会等待所有分区的确认。

我尝试过的:

  • 在阅读了 Adobe 和官方文档本身的精彩文档后,我理解了内部缓冲区的作用,很明显 KafkaProducer
    send()
    是异步的,不会阻塞调用线程,直到记录保存在分区中.
  • 在代码中,我将 linger 时间增加到很高的量,以查看主线程没有等待消息从缓冲区保留在分区中。

问题:

  • 我对 acks 配置的工作原理仍然有点不确定,并且想在做出决定之前确定一下。 acks 配置是否仅适用于发送者线程(从内部缓冲区获取一批消息并写入所有分区的线程)?不管这个值是多少,它都不会影响主线程,除非我们正在主线程中执行诸如
    Future.get()
    之类的阻塞操作。
  • 我们遇到了另一个问题,我们发现在高峰流量期间,在仪表板中完成 kafka 生产操作所需的时间有时会激增。我们的印象是,由于我们使用共享的集群来容纳我们的主题,因此在高峰流量期间,响应时间必然会激增。阅读这些文档后,我对响应时间峰值有一些怀疑:
    1. 指标的开始时间早于
      send()
      函数和结束时间 是在返回 RecordMetadata 并在调用线程的
      doOnSuccess
      doOnError
      块中调用指标发布函数之后。
    2. 基于这种设计,我假设无论发布的时间是什么,都是执行一系列步骤(即计算生产者元数据、计算分区、序列化等)所花费的时间,直到消息到达内部缓冲区并且不是 消息写入分区本身所花费的时间。 请验证此声明!
    3. 我现在正在尝试找出响应时间激增的问题可能是什么,我假设这是应用程序内的内部问题。
      • 是否当send()函数完成时,内部缓冲区中发送的消息应该被清除,如果这是一个阻塞操作,它可能会让应用程序线程等待写入缓冲区?
      • 如果这是真的,那么增加延迟或批量大小是否有助于解决此问题,因为内部缓冲区的清除操作不会如此频繁地发生?
asynchronous apache-kafka kafka-producer-api internals kafka-partition
1个回答
0
投票

基于这个设计,我假设无论发布什么时间都是 执行这一系列步骤所花费的时间(即计算生产者 元数据、计算分区、序列化等)直到消息 落在内部缓冲区中,而不是消息到达所花费的时间 写入分区本身

此说法属实。根据

ack
配置文档

acks=0 如果设置为零,那么生产者将不会等待任何 来自服务器的确认。记录将立即 添加到套接字缓冲区并视为已发送。

所以回调会在记录放入socket后通知,而不是内部缓冲区

此外,即使返回 Future,也不能保证

send()
方法完全非阻塞。您可以在
KafkaProducer.doSend()
代码中找到此代码:

accumulator.append(...,剩余WaitMs,...);

因此,如果内部缓冲区已满,

send()
实际上可能会阻塞。例如,如果您生成消息的速度比网络线程将消息发送到代理的速度快(即使不等待任何确认),则可能会发生这种情况

© www.soinside.com 2019 - 2024. All rights reserved.