Here's a diagram to help explain my problem better:

Now, keep in mind the following points:
To make sure I don't overwhelm the legacy system, a consumer will only send one request at a time. Any new message will wait for the current message to finish processing.
Since messages are blocked until the previous message is processed, I want to minimize the time a message will wait before it's processed. To do that I need messages to be distributed equally over the partitions. A massage must not be consumed by a busy consumer when another is free.
For example, if 8 messages are produced simultaneously, each message should be sent to one partition. Therefore, each message will be consumed by one consumer, ensuring the messages are processed concurrently without any lag.
Since the partitions are assigned correctly to the consumers, I had to assume the producer wasn't evenly delivering messages to the partitions. Which turned out to be the case. Here's what I tried so far to resolve the issue...
The most intuitive solution was to produce records without keys which will basically make the DefaultPartitioner behave like the RoundRobinPartitioner. unfortunately, this solution did not work.
Since using null keys didn't work, It made sense that messages were being sent in batches breaking the even distribution. Setting the batch size to 0 should've caused the producer to send messages one by one. That didn't work either.
This one was weird. The RoundRobinPartitioner distributed messages evenly, but it only used 4 out of the 8 partitions.
This made no difference.
I need the producer to send messages in Round Robin fashion one by one without batching. How can I do that?
I need the producer to send messages in Round Robin fashion without batching. How can I do that?
I've been meaning to post the answer for a while now. So here it is.
I discovered a bug with how the default round robin partitioner calculated the next partition number. So I implemented a custom partitioner. I called it a Retaining Round Robin partitioner, because it remembers the last partition number to which the last message was written. And then sends the next message to the next partition.
You can find the implementation on my GitHub repo under RetainingRoundRobinPartitioner.java
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With