在kafka中发送同步消息?

时间:2017-08-06 06:39:10

标签: apache-kafka kafka-producer-api

如何在kafka中发送同步消息?
实现它的一种方法是通过设置属性参数
max.in.flight.requests.per.connection = 1

但我想知道在kafka中是否有直接或替代方式发送同步消息。 (类似于producer.syncSend(...)等)。

5 个答案:

答案 0 :(得分:4)

生产者API从Future返回send。您可以致电Future#get来阻止,直到发送完成。

请参阅此example from the Javadocs

  

如果你想模拟一个简单的阻塞调用,你可以立即调用get()方法:

 byte[] key = "key".getBytes();
 byte[] value = "value".getBytes();
 ProducerRecord<byte[],byte[]> record = 
     new ProducerRecord<byte[],byte[]>("my-topic", key, value)
 producer.send(record).get();

答案 1 :(得分:1)

Thilo提出的答案是要走的路。通常,您关于使用max.in.flight.requests.per.connection = 1的建议用于启用重试,但不会丢失消息排序。它不是用于拥有同步生产者。

答案 2 :(得分:0)

按照Thilo的建议,您可以调用--scheduler django_celery_beat.schedulers:DatabaseScheduler 进行阻止,直到发送完成。但是,您可能会遇到一些性能问题,因为当生产者队列中有Future#get个元素,大小为batch.size的缓冲区已满或在buffer.memory毫秒之后,生产者就会开始发送。

如果推送到kafka的线程数量有限,则每次必须等待max.block.ms才能发送消息。因此,在某些情况下,您将更喜欢使用:

max.block.ms

答案 3 :(得分:0)

从我使用Kafka的经历来看:-)只有当您具有一个Producer线程并设置max.in.flight.requests.per.connection = 1(或retries,即retries时,才能保证消息产生的顺序。 = 0或两者皆有。

如果要扩展到多个生产者,则必须“确保”将由同一生产者实例生产将存储到同一分区的消息。

答案 4 :(得分:0)

当max.in.flight.requests.per.connection = 1时,这仅意味着消息的顺序在与同步无关的分区中得到保证。

Python代码(以防万一)。 对于同步发送,请确保以良好的超时阻止将来发生。

from kafka import KafkaProducer
from kafka.errors import KafkaError

#by default ack = 1, if ack = 'all' --> waits for acks from replicas 
producer = KafkaProducer(bootstrap_servers=['brokerIP:9092'], ack= 'all')


key = b'key'
value = b'value'

future = producer.send("my-topic", key=key, value=value)

# block on this future for sync sends
try:
    record_metadata = future.get(timeout=10)
except KafkaError:
    log.exception()
    pass

print (record_metadata.topic)
print (record_metadata.partition)
print (record_metadata.offset)

producer.flush()
producer.close()