I’m experimenting with Spring Kafka and I’m confused by the different ack modes.
By default, I believe it is set to BATCH which goes like:
- Call poll()
- poll() returns messages 1, 2, 3
- Process the messages sequentially (or concurrently)
- Call poll() again after all messages are processed
- Messages 1, 2, 3 are automatically committed, and messages 4, 5, 6 are returned
- Process repeats
One drawback I see to this though is that if you process messages 1 and 2, but 3 fails, you will have retry the entire batch.
I believe you can get around this by using AckMode RECORD or MANUAL_IMMEDIATE which “commits the offset after each record is processed by the listener” or by calling ack() on the acknowledgement object
So now it goes like:
- Call poll()
- poll() returns messages 1, 2, 3
- Process message 1, commit it
- Process message 2, commit it
- Process message 3, commit it
- Call poll() again after all messages are processed
- Messages 4, 5, 6 are returned
- Process repeats
What I’m confused about though is, what happens if I process the messages concurrently and something like this happens:
- Message 1 errors out
- Message 2 completes processing
- Message 3 completes processing
What is the offset set to in this case? 1? Will it return 2 and 3 again in that case? Or skip them and return 4 and 5?
I come from an SQS background where acking messages out of order is quite common and acceptable.