融合的Kafka使用者配置-session.timeout.ms和max.poll.interval.ms是如何关联的?

时间:2019-10-22 15:34:35

标签: apache-kafka kafka-consumer-api

我试图了解下面两个融合的使用者配置的默认值如何协同工作。

max.poll.interval.ms-根据相关文档,默认值为300,000 ms

session.timeout.ms-根据相关文档,默认值为10,000 ms

heartbeat.interval.ms-根据相关文档,默认值为3,000 ms

假设我在配置中使用了这些默认值。现在我在这里有一个问题。

例如,让我们假设一个消费者,消费者每3,000 ms发送一次心跳,而我的第一次轮询发生在时间戳t1,然后第二次轮询发生在t1 + 20,00 ms。那么这会导致重新平衡,因为超过了“ session.timeout.ms”?还是可以正常工作,因为消费者确实按照预期的时间戳发送了心跳信号?

1 个答案:

答案 0 :(得分:0)

在上一个线程Here中,还介绍了会话超时和最大轮询超时。让我也解释一下我对此的理解。

ConsumerRecords轮询(最终超时): 用于从最后消耗的偏移量或手动设置的偏移量开始按顺序从主题分区中获取数据。如果有可用记录,它将立即返回,否则将等待传递的超时。如果超时,将返回空记录。 民意测验API会继续调用以获取收到的任何新消息,并确保消费者的生命力。

session.timeout.ms 在每次轮询期间,消费者协调员都会向代理发送心跳信号,以确保消费者的会话处于活动状态。如果经纪人在session.timeout.ms经纪人之前没有收到任何心跳信号,则经纪人离开该消费者并重新平衡

您可以假设session.timeout.ms是代理等待从消费者获取心跳的最长时间,而heartbeat.interval.ms是消费者假设将心跳发送给Broker的预期时间。 多数民众赞成解释了heartbeat.interval.ms总是小于session.timeout.ms,因为理想情况下会话超时的1/3。

max.poll.interval.ms :使用使用者组管理时,两次poll()调用之间的最大延迟。这意味着使用者最大时间将在获取更多记录之前处于空闲状态。如果在此超时到期前未调用poll(),则该使用者被视为失败,并且该组将通过调用poll进行重新平衡以将分区重新分配给另一个使用者实例。 如果我们正在进行长时间批处理,则增加max.poll.interval.ms是有益的,但是请注意,增加此值可能会延迟组重新平衡,因为使用者只会在轮询调用中加入重新平衡。我们可以通过调整max.poll.records来保持最大轮询间隔较低,从而进行调整。

现在让我们讨论它们之间的关系。

消费者在调用轮询其检查心跳时,会话超时轮询超时在后台以如下方式进行:

  1. 消费者协调员检查消费者是否仍处于平衡状态(如果仍在进行平衡),然后等待协调员加入消费者。等待并致电民意调查。请注意,如果max.poll.interval.ms较大,则会花费更多时间进行重新平衡。
  2. 轮询和重新平衡完成后,协调器检查会话超时 如果会话超时已过期但没有看到成功的心跳,则旧协调器将断开连接,因此下一次轮询将尝试重新平衡。 因此,如果会话超时消费者协调器本身死了,并且呼叫轮询必须在重新平衡之前分配新的协调器,则会话超时直接取决于时间协调器的活动性。

  3. 在会话超时检查协调器之后,如果轮询超时已过期,则验证 heartbeat.pollTimeoutExpired ,这意味着前台线程在对poll()的调用之间停滞了,因此成员明确离开小组并致电民意调查以加入新消费者而不是整个消费者组协调员。

  4. 在会话超时和轮询超时验证之后以及发送心跳状态之前,消费者协调员检查心跳超时,如果心跳超过最大延迟心跳时间,则暂停/等待重试退回并再次轮询。
  5. 如果心跳时间也未超过限制,那么消费者协调员将发送sendHeartbeatRequest
  6. 如果sendHeartbeatRequest成功线程将重置心跳时间并调用轮询,但是如果失败并且使用者组未处于重新平衡状态,它将唤醒使用者组协调器以再次调用轮询。

正如共享链接轮询中所提到的那样,轮询是独立于心跳的,因此在轮询期间,如果poll很大,心跳仍然允许发送心跳,这确保您的线程处于活动状态,意味着会话超时不会直接链接到poll。

session.timeout.ms: 接收心跳的最长时间

max.poll.interval.ms: 在独立处理线程上的最长时间

因此,如果将max.poll.interval.ms设置为300,000,则下一次轮询将有300,000 ms,这意味着使用者线程最多需要300,000 ms才能完成处理。在两次之间,心跳将继续在heartbeat.interval.ms(即3,000)处指示心跳仍在发送心跳请求,并在session.timeout.ms(即10,000个协调器)死掉之前没有心跳的情况下,并调用poll来重新分配新的协调器并重新平衡