producer.poll(0)不会产生任何消息,但是producer.flush()可以工作

时间:2019-12-04 09:05:42

标签: python apache-kafka confluent confluent-kafka

当我使用producer.flush()时有效,但根据kafka confluent issue却表现不佳,但是如建议的那样,我使用producer.poll(0)但对主题没有任何消息,是否需要任何配置或我这里缺少什么?

self.producer.produce(topic.value, data.encode('utf-8'), callback=self.delivery_report)

self.producer.poll(0)  # -> doesn't work
self.producer.flush()  # -> works

2 个答案:

答案 0 :(得分:0)

问题是poll()不能使生产者同步,只是调用事件并触发您注册的任何callback()

您在前一行中发送的消息最肯定仍在生产者缓冲区中,也就是说,它甚至没有从您的网卡中发出,因此代理人不认可它,而您已经回调了注册未触发。这些内部缓冲区由内部kafka线程清空,这些线程等待达到一定时间/大小,然后将消息发送给代理。 poll()呼叫在那里做零工作(只要生产者以前没有发送任何消息),因为(最肯定的)消息没有到达kafka经纪人(它甚至没有从制作人的主机中消失)。

调用flush()时,就是使生产者成为同步者:它将使客户端等待任何未完成的消息传递到代理。这就是为什么只有在调用flush()之后才能产生结果的原因。

Edenhill 很好地解释了in this snippet

答案 1 :(得分:0)

消息没有发送到kafka,因为没有时间执行此操作。您的应用提前终止。

这将起作用:

self.producer.produce(topic.value, data.encode('utf-8'), callback=self.delivery_report)
timer.sleep(1) -- sleep for one seconds. 
self.producer.poll(0) 

生产者有两个缓冲区。第一个发送缓冲区,第二个响应缓冲区(来自kafka的响应)。

方法produce(...)-正在向发送缓冲区添加新消息。默认情况下,后台线程尝试尽快发送消息,但是仍然需要一些时间来执行此操作。

方法poll(0)-正在检查响应缓冲区并正在执行回调方法。如果缓冲区为空,则什么也不会发生。

方法flush()-正在检查两个缓冲区,直到所有消息都将被处理并且正在执行回调方法为止。退出应用程序之前,请使用此方法。

用法示例。

def send(topic,message,callback_report):
   producer.produce(topic,message,callback=callback_report)
   producer.pool(0) // execute callback for previous messages,  

for msg in big_collection_of_messages:
  send('blabla',msg,delivery_report)


producer.flush()
//END OF APPLICATION 

注意。这种解释大大简化了。