You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jira@kafka.apache.org by "Luke Chen (Jira)" <ji...@apache.org> on 2021/07/31 10:15:00 UTC
[jira] [Commented] (KAFKA-9965) Uneven distribution with
RoundRobinPartitioner in AK 2.4+
[ https://issues.apache.org/jira/browse/KAFKA-9965?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17390950#comment-17390950 ]
Luke Chen commented on KAFKA-9965:
----------------------------------
[~cmccabe] [~ijuma] , I have a proposal for this issue. Currently in WIP PR: [https://github.com/apache/kafka/pull/8690,] we tried to fix the `RoundRobinPartitioner` by decrement the counter in `onNewBatch` callback. However, this fix can't fix all 3rd party partitioners if they don't implement the `onNewBatch` method.
The root cause should be that we added a new method `onNewBatch` in Kafka 2.4, and some old 3rd-party partitioners don't implement it, which cause we call partitioner twice. These partitioners don't implement `onNewBatch` method means partitioners won't have different partition on new batch, ex: RoundRobinPartitioner. We should not have another call to partitioner in these cases. I'm thinking we can throw exception for default onNewBatch method like this:
{code:java}
default void onNewBatch(String topic, Cluster cluster, int prevPartition) {
// orignally, the default implementation is empty, now, we'll throw exception here.
throw new UnsupportedOperationException();
}{code}
This way, we don't change the API, and also we can know the partitioner doesn't implement the `onNewBatch` method, and we can directly use the previously paritioner's partition in producer, ex:
{code:java}
// KafkaProducer#doSend
private Future<RecordMetadata> doSend(ProducerRecord<K, V> record, Callback callback) {
...
// first time we call partitioner
int partition = partition(record, serializedKey, serializedValue, cluster);
...
log.trace("Attempting to append record {} with callback {} to topic {} partition {}", record, callback, record.topic(), partition);
// try to append the record, and abort when new batch
RecordAccumulator.RecordAppendResult result = accumulator.append(tp, timestamp, serializedKey,
serializedValue, headers, interceptCallback, remainingWaitMs, true, nowMs);
// new batch case
if (result.abortForNewBatch) {
int prevPartition = partition;
// partitioner.onNewBatch(record.topic(), cluster, prevPartition);
// here, we bypass the partition() call if `onNewBatch` throw exception
try {
partitioner.onNewBatch(record.topic(), cluster, prevPartition);
// 2nd time we call partitioner. If onNewBatch doesn't get implemented, we won't call it
partition = partition(record, serializedKey, serializedValue, cluster);
} catch (UnsupportedOperationException e) {
// ignore the exception since the partitioner doesn't care about new batch case
}
log.trace("Retrying append due to new batch creation for topic {} partition {}. The old partition was {}", record.topic(), partition, prevPartition);
...
{code}
What do you think?
> Uneven distribution with RoundRobinPartitioner in AK 2.4+
> ---------------------------------------------------------
>
> Key: KAFKA-9965
> URL: https://issues.apache.org/jira/browse/KAFKA-9965
> Project: Kafka
> Issue Type: Bug
> Components: producer
> Affects Versions: 2.4.0, 2.5.0, 2.4.1
> Reporter: Michael Bingham
> Priority: Major
>
> {{RoundRobinPartitioner}} states that it will provide equal distribution of records across partitions. However with the enhancements made in KIP-480, it may not. In some cases, when a new batch is started, the partitioner may be called a second time for the same record:
> [https://github.com/apache/kafka/blob/2.4/clients/src/main/java/org/apache/kafka/clients/producer/KafkaProducer.java#L909]
> [https://github.com/apache/kafka/blob/2.4/clients/src/main/java/org/apache/kafka/clients/producer/KafkaProducer.java#L934]
> Each time the partitioner is called, it increments a counter in {{RoundRobinPartitioner}}, so this can result in unequal distribution.
> Easiest fix might be to decrement the counter in {{RoundRobinPartitioner#onNewBatch}}.
>
--
This message was sent by Atlassian Jira
(v8.3.4#803005)