Skip to content

KAFKA-19500: kafka-consumer-groups.sh should fail quickly if the partition leader is unavailable#20168

Merged
AndrewJSchofield merged 6 commits into
apache:trunkfrom
xijiu:19500
Jul 21, 2025
Merged

KAFKA-19500: kafka-consumer-groups.sh should fail quickly if the partition leader is unavailable#20168
AndrewJSchofield merged 6 commits into
apache:trunkfrom
xijiu:19500

Conversation

@xijiu

@xijiu xijiu commented Jul 15, 2025

Copy link
Copy Markdown
Contributor
  1. Add check leader missing logic in method
    ConsumerGroupCommand.ConsumerGroupService#prepareOffsetsToReset in
    order to fail quickly
  2. Add some tests

Reviewers: TaiJuWu tjwu1217@gmail.com, Lan Ding isDing_L@163.com,
Ken Huang s7133700@gmail.com, Andrew Schofield
aschofield@confluent.io

@github-actions github-actions Bot added the triage PRs from the community label Jul 15, 2025
@xijiu

xijiu commented Jul 15, 2025

Copy link
Copy Markdown
Contributor Author

The all methods which depend on Admin#listOffsets are as follows:

  • offsetsUtils.resetToOffset
  • offsetsUtils.resetToEarliest
  • offsetsUtils.resetToLatest
  • offsetsUtils.resetByShiftBy
  • offsetsUtils.resetToDateTime
  • offsetsUtils.resetByDuration
  • offsetsUtils.resetFromFile
  • offsetsUtils.resetToCurrent

And they are all called in method ConsumerGroupCommand.ConsumerGroupService#prepareOffsetsToReset, so we should add the check logic in this method.

@github-actions github-actions Bot added tools small Small PRs labels Jul 15, 2025
@xijiu xijiu added ci-approved tools small Small PRs and removed tools small Small PRs labels Jul 15, 2025

@AndrewJSchofield AndrewJSchofield left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. Just one minor comment.

private void checkAllTopicPartitionsHaveLeader(Collection<TopicPartition> partitionsToReset) {
List<TopicPartition> partitionsWithoutLeader = filterNoneLeaderPartitions(partitionsToReset);
if (!partitionsWithoutLeader.isEmpty()) {
// append the TopicPartition list string

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: You could do this string concatenation much more neatly with something like

String partitionStr = partitionsWithoutLeader.stream().map(TopicPartition::toString).collect(Collectors.joining(","));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AndrewJSchofield Thanks very much for CR, it's indeed much neater. I have fixed it, PTAL

@m1a2st m1a2st left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank @xijiu for this patch, a little comment

assertThrows(OptionException.class, () -> getConsumerGroupService(cgcArgs));
}

@Timeout(60)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: No need to add @Timeout here, @ClusterTest already includes a timeout setting.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m1a2st Thanks very much, the @Timeout is redundant, and I have remove it, PTAL

@github-actions github-actions Bot removed the triage PRs from the community label Jul 16, 2025

@TaiJuWu TaiJuWu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@AndrewJSchofield AndrewJSchofield left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could do with a little more work. If I create a topic T1 with 1 partition, the following command bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --reset-offsets --group CG1 --to-earliest --topic T1:1 --execute still hangs for a long time, even though it has called Admin.describeTopics.

I think it can be improved for the case of a non-existent topic of an existing topic. Seems like it's worth fixing this at the same time.

@xijiu

xijiu commented Jul 17, 2025

Copy link
Copy Markdown
Contributor Author

I think this could do with a little more work. If I create a topic T1 with 1 partition, the following command bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --reset-offsets --group CG1 --to-earliest --topic T1:1 --execute still hangs for a long time, even though it has called Admin.describeTopics.

I think it can be improved for the case of a non-existent topic of an existing topic. Seems like it's worth fixing this at the same time.

Good find! It's indeed hangs when a non-existent TopicPartition of an existing topic.

I have added some logic to determine whether the target TopicPartitions actually exists, PTAL

@AndrewJSchofield AndrewJSchofield left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates. Just a few minor comments now.

List<TopicPartition> partitionsNotExistList = filterNotExistPartitions(partitionsToReset);
if (!partitionsNotExistList.isEmpty()) {
String partitionStr = partitionsNotExistList.stream().map(TopicPartition::toString).collect(Collectors.joining(","));
throw new UnknownTopicOrPartitionException("The partitions \"" + partitionStr + "\" does not exist");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Grammar "do not exist" I think.

}
}

private List<TopicPartition> filterNotExistPartitions(Collection<TopicPartition> topicPartitions) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: filterNonExistentPartitions is probably a bit better.

.toList();

return topicPartitions.stream().filter(element -> !existPartitions.contains(element)).toList();
} catch (Exception e) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency, we tend to catch (InterruptedException | ExecutionException e) in this source file.

@AndrewJSchofield

Copy link
Copy Markdown
Member

Also please merge latest changes from trunk. Hopefully you'll get a clean test run then.

@xijiu

xijiu commented Jul 18, 2025

Copy link
Copy Markdown
Contributor Author

@AndrewJSchofield Thanks for the code review, and I have fixed them and merged the latest changes from trunk, PTAL

@DL1231 DL1231 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@AndrewJSchofield AndrewJSchofield left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. Looks good to me.

@AndrewJSchofield
AndrewJSchofield merged commit f188a31 into apache:trunk Jul 21, 2025
24 checks passed
}

// check the partitions have leader
List<TopicPartition> partitionsWithoutLeader = filterNoneLeaderPartitions(partitionsToReset);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if there is a topic having three partitions, and the t-2 partition is offline, then if partitionsToReset is t-0,t-1, filterNoneLeaderPartitions will return t-2, causing the tool to fail. Is it expected?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fair enough.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chia7712@chia7712-ubuntu:~/project/kafka$ ./bin/kafka-consumer-groups.sh \
  --bootstrap-server 172.20.10.2:20001 \
  --reset-offsets \
  --to-earliest \
  --execute \
  --group perf-consumer-19460 \
  --topic chia:1

Error: Executing consumer group command failed due to The partitions "chia-2" have no leader
org.apache.kafka.common.errors.LeaderNotAvailableException: The partitions "chia-2" have no leader

It is indeed a bug that unrelated topic partitions could fail the tool.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filterNoneLeaderPartitions needs to get fixed since it could return unrelated topic partitions.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's a very good point. Thanks for finding it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

file #20235 to fix it.

produceConsumeAndShutdown(cluster, topic, group, 2, GroupProtocol.CLASSIC);
assertDoesNotThrow(() -> resetOffsets(service));
// shutdown a broker to make some partitions missing leader
cluster.shutdownBroker(0);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we wait to ensure it has shut down correctly?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The shutdown already has a 5-minute timeout by default.

JimmyWang6 added a commit to JimmyWang6/jimmy-KAFKA-14048 that referenced this pull request Jul 31, 2025
JimmyWang6 added a commit to JimmyWang6/jimmy-KAFKA-14048 that referenced this pull request Jul 31, 2025
AndrewJSchofield pushed a commit that referenced this pull request Jul 31, 2025
…artition offline (#20235)

See: #20168 (comment)

add follow test case:

Given a topic with three partitions, where partition `t-2` is offline,
if partitionsToReset contains only `t-1`, the method
filterNoneLeaderPartitions incorrectly includes `t-2` in the result,
leading to a failure in the tool.

Reviewers: Chia-Ping Tsai <chia7712@gmail.com>, Jhen-Yung Hsu
 <jhenyunghsu@gmail.com>, Ken Huang <s7133700@gmail.com>, Andrew
 Schofield <aschofield@confluent.io>
airlock-confluentinc Bot pushed a commit to confluentinc/kafka that referenced this pull request Aug 6, 2025
…artition offline (apache#20235)

See: apache#20168 (comment)

add follow test case:

Given a topic with three partitions, where partition `t-2` is offline,
if partitionsToReset contains only `t-1`, the method
filterNoneLeaderPartitions incorrectly includes `t-2` in the result,
leading to a failure in the tool.

Reviewers: Chia-Ping Tsai <chia7712@gmail.com>, Jhen-Yung Hsu
 <jhenyunghsu@gmail.com>, Ken Huang <s7133700@gmail.com>, Andrew
 Schofield <aschofield@confluent.io>
k-apol pushed a commit to k-apol/kafka that referenced this pull request Aug 8, 2025
…rtition leader is unavailable (apache#20168)

1. Add check leader missing logic in method
`ConsumerGroupCommand.ConsumerGroupService#prepareOffsetsToReset` in
order to fail quickly
2. Add some tests

Reviewers: TaiJuWu <tjwu1217@gmail.com>, Lan Ding <isDing_L@163.com>,
 Ken Huang <s7133700@gmail.com>, Andrew Schofield
 <aschofield@confluent.io>
k-apol pushed a commit to k-apol/kafka that referenced this pull request Aug 8, 2025
…artition offline (apache#20235)

See: apache#20168 (comment)

add follow test case:

Given a topic with three partitions, where partition `t-2` is offline,
if partitionsToReset contains only `t-1`, the method
filterNoneLeaderPartitions incorrectly includes `t-2` in the result,
leading to a failure in the tool.

Reviewers: Chia-Ping Tsai <chia7712@gmail.com>, Jhen-Yung Hsu
 <jhenyunghsu@gmail.com>, Ken Huang <s7133700@gmail.com>, Andrew
 Schofield <aschofield@confluent.io>
JimmyWang6 added a commit to JimmyWang6/jimmy-KAFKA-14048 that referenced this pull request Aug 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants