如何强制消费者阅读kafka

时间:2017-08-29 13:15:34

标签: apache-kafka kafka-python

我有一个从1 Kafka-producer生成的URL流下载特定Web内容的应用程序。我创建了一个包含5个分区的主题,并且有5个kafka-consumers。但是,网页下载超时为60秒。 当其中一个URL被下载时,服务器会假定消息丢失并将数据重新发送给不同的消费者。

我已经尝试了

中提到的所有内容

Kafka consumer configuration / performance issues

https://github.com/spring-projects/spring-kafka/issues/202

但我每次都会遇到不同的错误。

是否可以将特定消费者与kafka中的分区联系起来? 我正在使用kafka-python作为我的应用程序

3 个答案:

答案 0 :(得分:4)

我错过了Kafka-python的文档。我们可以使用TopicPartition类为特定的消费者分配一个分区。

http://kafka-python.readthedocs.io/en/master/

>>> # manually assign the partition list for the consumer
>>> from kafka import TopicPartition
>>> consumer = KafkaConsumer(bootstrap_servers='localhost:1234')
>>> consumer.assign([TopicPartition('foobar', 2)])
>>> msg = next(consumer)

答案 1 :(得分:1)

我从未使用过Python客户端,但Java支持assign方法,您可以使用subscribe方法而不是double percent = 1 - (etSWNum / 100.0); 来请求为主题分配特定分区。当然,您失去了自动重新平衡功能,您必须手动处理这些用例。

答案 2 :(得分:0)

也许我猜你的情况会发生什么。如果您的消费者从kafka获取网址,然后去下载内容,那么您说它需要花费大约60秒才能完成。所以你的消费者因为下载而阻止它,并且无法向kafka服务器发送心跳。因此,kafka服务器认为此消费者已关闭,因此它会进行组重新平衡,并将未提交的消息重新发送给其他消费者。

因此,您可以尝试两种解决方案:

  1. 将配置_Engine.Script.test( new PropertyBag { ["test"] = 123, ["cat"] = "lolcat" } ); 设置为60000或更大。默认值为30秒,对您来说还不够。

  2. 更好的解决方案是使用多线程来实现。当您的消费者从kafka获取消息,然后启动一个新线程来下载内容时,它不会阻止consumer.poll,因此它可以很好地工作。