https://www.safaribooksonline.com/library/view/kafka-the-definitive/9781491936153/ch04.html提到“只要消费者定期发送心跳,就会认为它是活着的,并且处理来自其分区的消息。事实上,轮询消息的行为是什么原因导致消费者发送这些心跳。如果消费者停止发送心跳的时间足够长,其会话将超时,小组协调员会认为它已经死亡并触发重新平衡。“
类似地https://kafka.apache.org/090/javadoc/index.html?org/apache/kafka/clients/consumer/KafkaConsumer.html指定“代理将使用心跳机制自动检测测试组中的失败进程。消费者将自动定期ping集群,这使集群知道它处于活动状态只要消费者能够做到这一点,它就被认为是活着的,并保留从分配给它的分区消费的权利。如果它停止心跳超过session.timeout.ms的一段时间,那么它将被视为死亡并将其分区分配给另一个进程。“
在我的应用程序中,处理从先前poll()接收的消息可能需要几个小时才能调用另一个poll()。注意:我禁用自动提交,因为我并不总是知道处理所有以前的消息需要多长时间。
a)是否会导致小组协调员将消费者视为死亡或不活跃?
b)是否有其他方法可以将心跳消息发送给组协调器以使会话保持活动状态?
c)session.timeout.ms会对保持消费者活着/活跃有任何影响吗?
答案 0 :(得分:4)
a)是的,如果你没有拨打poll()
的时间超过session.timeout.ms
卡夫卡认为消费者已经死亡。
b)作为替代方案,您可以在处理过程中调用poll()
(即,与处理交错)以触发心跳(并在每个"真实"轮询之前寻找)。使用额外的处理线程也是可能的,允许主线程定期轮询以发送心跳。 但是,您需要确保检测到处理线程上的失败(正确执行哪些操作)!
c)您可以增加超时值,但是,这可能不是您想要的,就像您的消费者失败一样,很快就会检测到这个失败。
您描述的问题实际上是已知的,并且消费者行为将来可能会发生变化。已经有人讨论过它。有关详细信息,请参阅KIP-62。
<强>更新强>
由于Kafka 0.10.1
消费者有两个配置参数:max.poll.interval.ms
和session.timeout.ms
。第一个是两个连续轮询之间的最大时间,而第二个是心跳超时。心跳是通过额外的线程发送的,因此现在与调用poll()
分离。因此,增加max.poll.interval.ms
不会产生负面影响,即不能快速检测到整个客户端的故障(无心跳)。