Search code examples
apache-kafkakafka-producer-api

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


Does acknowledgement modes ('0','1','all') have any impact, when we send messages using asynchronous send() call?

I have tried measuring the send call latency (that is, by recording time before and after call to send() method) and observed that both (asynchronous send, acks=1) and (asynchronous send, acks=all) took same time.

However, there is a clear difference in throughput numbers.

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

I thought send call will be blocked when we use acks=all even in asynchronous mode. Can someone explain how acknowledgement modes ('0','1','all') work in asynchronous mode?


Solution

  • According to the 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.

    So, one thing is certain that the asynchronous "send" does not really care about what the "acks" config is. All it does is push the message into a buffer. Once this buffer starts getting processed (controlled by linger.ms and batch.size properties), then "acks" is checked.

    If acks=0 -> Just fire and forget. Producer won't wait for an acknowledgement.

    If acks=1-> Acknowledgement is sent by the broker when message is successfully written on the leader.

    If acks=all -> Acknowledgement is sent by the broker when message is successfully written on all replicas.

    In case of 1 and all, this becomes a blocking call as the producer will wait for an acknowledgement but, you might not notice this as it happens on a parallel thread. In case of acks=all, it is expected that it will take a little longer for the ack to arrive than acks=1 (network latency and number of replicas being the obvious reasons).

    Further, you should configure "retries" property in your async-producer so that, if an acknowledgement fails (due to any reason e.g. packet corrupted/lost), the producer knows how many times it should try again to send the message (increase the guarantee of delivery).

    Lastly: "However, there is a clear difference in throughput numbers." -- That's true because of the acknowledgement latency from the broker to the producer thread.

    Hope that helps! :)