kafka中异步发送的确认模式有什么影响?

What is the impact of acknowledgement modes in asynchronous send in kafka?

当我们使用异步 send() 调用发送消息时,确认模式('0'、'1'、'all')是否有任何影响?

我已经尝试测量发送调用延迟(即通过记录调用 send() 方法前后的时间)并观察到(异步发送,acks=1)和(异步发送, acks=all) 花费了相同的时间。

但是,吞吐量数字存在明显差异。

producer.send(record, new ProducerCallback(record));

我认为当我们使用 acks=all 时即使在异步模式下发送调用也会被阻塞。有人可以解释确认模式('0'、'1'、'all')如何在异步模式下工作吗?

根据 docs:

public Future send(ProducerRecord record, Callback callback)

Asynchronously send a record to a topic and invoke the provided callback when the send has been acknowledged. The send is asynchronous and this method will return immediately once the record has been stored in the buffer of records waiting to be sent. This allows sending many records in parallel without blocking to wait for the response after each one.

所以,可以肯定的是,异步 "send" 并不真正关心 "acks" 配置是什么。它所做的只是将消息推入缓冲区。一旦这个 缓冲区 开始被处理(由 linger.ms 和 batch.size 属性控制),然后 "acks" 被检查。

If acks=0 -> 开火就不管了。生产者不会等待确认。

如果 acks=1-> 当消息成功写入领导者时,代理发送确认。

如果 acks=all -> 当消息成功写入所有副本时,代理发送确认。

在 1 和所有情况下,这变成了阻塞调用,因为生产者将等待确认,但是,您可能不会注意到这一点,因为它发生在并行线程上。在 acks=all 的情况下,预计 ack 到达的时间会比 acks=1 稍长(网络延迟和副本数是明显的原因)。

此外,您应该在 async-producer 中配置 "retries" 属性,这样,如果确认失败(由于任何原因,例如数据包 corrupted/lost),生产者知道应该重试发送消息多少次(增加传递保证)。

最后:"However, there is a clear difference in throughput numbers." -- 这是真的,因为从代理到生产者线程的确认延迟。

希望对您有所帮助! :)