处理卡夫卡消息需要很长时间

时间:2019-11-25 01:58:04

标签: apache-kafka kafka-consumer-api kafka-python

我有一个Python进程(或一组在用户组中并行运行的进程),该进程根据来自某些主题的Kafka消息输入来处理数据。通常,每条消息都会得到快速处理,但是有时,根据消息的内容,可能会花费很长时间(几分钟)。在这种情况下,Kafka经纪人将客户端与组断开连接并启动重新平衡。我可以将session_timeout_ms设置为一个非常大的值,但是那会超过10分钟,这意味着如果客户端死亡,则群集将无法在10分钟内正确地重新平衡。这似乎是一个坏主意。而且,大多数消息(大约98%)都是快速的,因此只为1-2%的消息付出这样的代价似乎是浪费的。 OTOH,大消息的频率足够频繁,足以引起大量的重新平衡并导致大量的性能损失(因为在组进行重新平衡时,什么也做不了,然后“死者”客户端再次重新加入并导致了另一次重新平衡)。

所以,我想知道,还有其他方法可以处理需要很长时间才能处理的消息吗?有没有办法手动启动心跳以告诉经纪人“没关系,我还活着,我只是在处理消息”?我以为Python客户端(我使用kafka-python 1.4.7)应该为我这样做,但是似乎没有发生。而且,API似乎根本没有单独的“心跳”功能。而且据我了解,实际上,调用poll()会得到我的下一条消息-我什至没有用完当前消息,而且还会弄乱面向Kafka使用者的迭代器API,在Python中使用它非常方便。

如果很重要,如果我没记错的话,Kafka集群是Confluent,版本2.3。

1 个答案:

答案 0 :(得分:2)

在Kafka 0.10.1+中,Kafka轮询和会话心跳相互分离。 您可以得到解释here

max.poll.interval.ms 允许在超时之前按消费者实例完成处理的时间是多少,这意味着处理时间所花费的时间是否超过max.poll.interval.ms的时间,消费者组将假定将其从消费者组中删除并调用重新平衡。

要增加此长度,将增加预期轮询之间的间隔,从而使消费者有更多时间来处理从poll(long)返回的一批记录。 但是与此同时,这也会延迟组重新平衡,因为消费者只会在轮询调用中加入重新平衡。

session.timeout.ms 是用于标识消费者是否仍然存活并按定义的时间间隔(heartbeat.interval.ms)发送心跳的超时。通常,经验法则是heartbeat.interval.ms应该是会话超时的1/3,以便在网络故障的情况下,用户在会话超时之前最多可以错过3次心跳。

  1. session.timeout.ms:较低的值可以更快地检测到故障。

  2. max.poll.interval.ms:较大的值将减少由于增加处理时间而导致的故障风险,但会增加重新平衡时间。

注意:消费者组消耗的大量分区和主题也会影响总体重新平衡时间

如果您真的想摆脱重新平衡的另一种方法,则可以使用分区分配在每个使用者实例上手动分配分区。在这种情况下,每个使用者实例将使用其自己分配的分区独立运行。但是在那种情况下,您将无法利用重新平衡功能来自动分配分区。