-
Notifications
You must be signed in to change notification settings - Fork 14.4k
KAFKA-12464: follow up PR to refactor codes and add logs #10645
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -178,17 +178,17 @@ private Map<String, List<TopicPartition>> constrainedAssign(Map<String, Integer> | |
|
||
int minQuota = (int) Math.floor(((double) totalPartitionsCount) / numberOfConsumers); | ||
int maxQuota = (int) Math.ceil(((double) totalPartitionsCount) / numberOfConsumers); | ||
// the expected number of members with maxQuota assignment | ||
int expectedNumMembersHavingMorePartitions = totalPartitionsCount % numberOfConsumers; | ||
// the number of members with exactly maxQuota partitions assigned | ||
int numMembersHavingMorePartitions = 0; | ||
// the expected number of members with over minQuota assignment | ||
int expectedNumMembersAssignedOverMinQuota = totalPartitionsCount % numberOfConsumers; | ||
// the number of members with over minQuota partitions assigned | ||
int numMembersAssignedOverMinQuota = 0; | ||
|
||
// initialize the assignment map with an empty array of size maxQuota for all members | ||
Map<String, List<TopicPartition>> assignment = new HashMap<>( | ||
consumerToOwnedPartitions.keySet().stream().collect(Collectors.toMap(c -> c, c -> new ArrayList<>(maxQuota)))); | ||
|
||
List<TopicPartition> assignedPartitions = new ArrayList<>(); | ||
// Reassign as many previously owned partitions as possible | ||
// Reassign previously owned partitions to the expected number | ||
for (Map.Entry<String, List<TopicPartition>> consumerEntry : consumerToOwnedPartitions.entrySet()) { | ||
String consumer = consumerEntry.getKey(); | ||
List<TopicPartition> ownedPartitions = consumerEntry.getValue(); | ||
|
@@ -203,10 +203,10 @@ private Map<String, List<TopicPartition>> constrainedAssign(Map<String, Integer> | |
assignedPartitions.addAll(ownedPartitions); | ||
} | ||
unfilledMembers.add(consumer); | ||
} else if (ownedPartitions.size() >= maxQuota && numMembersHavingMorePartitions < expectedNumMembersHavingMorePartitions) { | ||
// consumer owned the "maxQuota" of partitions or more, and we're still under the number of expected max capacity members | ||
// so keep "maxQuota" of the owned partitions, and revoke the rest of the partitions | ||
numMembersHavingMorePartitions++; | ||
} else if (ownedPartitions.size() >= maxQuota && numMembersAssignedOverMinQuota < expectedNumMembersAssignedOverMinQuota) { | ||
// consumer owned the "maxQuota" of partitions or more, and we're still under the number of expected members | ||
// with more than the minQuota partitions, so keep "maxQuota" of the owned partitions, and revoke the rest of the partitions | ||
numMembersAssignedOverMinQuota++; | ||
List<TopicPartition> maxQuotaPartitions = ownedPartitions.subList(0, maxQuota); | ||
consumerAssignment.addAll(maxQuotaPartitions); | ||
assignedPartitions.addAll(maxQuotaPartitions); | ||
|
@@ -218,8 +218,10 @@ private Map<String, List<TopicPartition>> constrainedAssign(Map<String, Integer> | |
consumerAssignment.addAll(minQuotaPartitions); | ||
assignedPartitions.addAll(minQuotaPartitions); | ||
allRevokedPartitions.addAll(ownedPartitions.subList(minQuota, ownedPartitions.size())); | ||
// this consumer is potential maxQuota candidate since we're still under the number of expected max capacity members | ||
if (numMembersHavingMorePartitions < expectedNumMembersHavingMorePartitions) { | ||
// this consumer is potential maxQuota candidate since we're still under the number of expected members | ||
// with more than the minQuota partitions. Note, if the number of expected members with more than | ||
// the minQuota partitions is 0, it means minQuota == maxQuota, so they won't be put into unfilledMembers | ||
if (numMembersAssignedOverMinQuota < expectedNumMembersAssignedOverMinQuota) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Agree! I refer to your suggested change except
This should make it more clear.
Not excatly. After what we've changed to add potential maxQuota members into unfilledMembers, the unassignedPartitions size will not always >= unfilledMembers size. There will be cases that the unfilledMembers won't get any additional partition. Here's the example (also in new added tests) In this situation, the maxQuota is 3, minQuota is 2, expectedNumMembersAssignedOverMinQuota is 1. so, after 1st reassign previously owned partitions phase, the |
||
unfilledMembers.add(consumer); | ||
} | ||
} | ||
|
@@ -242,6 +244,9 @@ private Map<String, List<TopicPartition>> constrainedAssign(Map<String, Integer> | |
if (unfilledMembers.isEmpty()) { | ||
// Should not enter here since we have calculated the exact number to assign to each consumer | ||
// There might be issues in the assigning algorithm, or maybe assigning the same partition to two owners. | ||
int currentPartitionIndex = unassignedPartitions.indexOf(unassignedPartition); | ||
log.error("No more unfilled consumers to be assigned. The remaining unassigned partitions are: {}", | ||
unassignedPartitions.subList(currentPartitionIndex, unassignedPartitions.size())); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Make sense. Added! |
||
throw new IllegalStateException("No more unfilled consumers to be assigned."); | ||
} | ||
unfilledConsumerIter = unfilledMembers.iterator(); | ||
|
@@ -255,27 +260,35 @@ private Map<String, List<TopicPartition>> constrainedAssign(Map<String, Integer> | |
partitionsTransferringOwnership.put(unassignedPartition, consumer); | ||
|
||
int currentAssignedCount = consumerAssignment.size(); | ||
int expectedAssignedCount = numMembersHavingMorePartitions < expectedNumMembersHavingMorePartitions ? maxQuota : minQuota; | ||
int expectedAssignedCount = numMembersAssignedOverMinQuota < expectedNumMembersAssignedOverMinQuota ? maxQuota : minQuota; | ||
if (currentAssignedCount == expectedAssignedCount) { | ||
if (currentAssignedCount == maxQuota) { | ||
numMembersHavingMorePartitions++; | ||
numMembersAssignedOverMinQuota++; | ||
} | ||
unfilledConsumerIter.remove(); | ||
} | ||
} | ||
|
||
if (!unfilledMembers.isEmpty()) { | ||
// we expected all the remaining unfilled members have minQuota partitions and we're already at the allowed number | ||
// of max capacity members. Otherwise, there must be error here. | ||
if (numMembersHavingMorePartitions != expectedNumMembersHavingMorePartitions) { | ||
throw new IllegalStateException(String.format("We haven't reached the allowed number of max capacity members, " + | ||
"but no more partitions to be assigned to unfilled consumers: %s", unfilledMembers)); | ||
// we expected all the remaining unfilled members have minQuota partitions and we're already at the expected number | ||
// of members with more than the minQuota partitions. Otherwise, there must be error here. | ||
if (numMembersAssignedOverMinQuota != expectedNumMembersAssignedOverMinQuota) { | ||
log.error("Current number of members with more than the minQuota partitions: {}, is less than the expected number " + | ||
"of members with more than the minQuota partitions: {}, and no more partitions to be assigned to the remaining unfilled consumers: {}", | ||
numMembersAssignedOverMinQuota, expectedNumMembersAssignedOverMinQuota, unfilledMembers); | ||
throw new IllegalStateException("We haven't reached the expected number of members with " + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I included most info in the error log, and just put simple error message in exception. |
||
"more than the minQuota partitions, but no more partitions to be assigned"); | ||
} else { | ||
for (String unfilledMember : unfilledMembers) { | ||
int assignedPartitionsCount = assignment.get(unfilledMember).size(); | ||
if (assignedPartitionsCount != minQuota) { | ||
throw new IllegalStateException(String.format("Consumer: [%s] should have %d partitions, but got %d partitions, " + | ||
"and no more partitions to be assigned", unfilledMember, minQuota, assignedPartitionsCount)); | ||
log.error("Consumer: [{}] should have {} partitions, but got {} partitions, and no more partitions " + | ||
"to be assigned. The remaining unfilled consumers are: {}", unfilledMember, minQuota, assignedPartitionsCount, unfilledMembers); | ||
throw new IllegalStateException(String.format("Consumer: [%s] doesn't reach minQuota partitions, " + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I included most info in the error log, and just put simple error message in exception. |
||
"and no more partitions to be assigned", unfilledMember)); | ||
} else { | ||
log.trace("skip over this unfilled member: [{}] because we've reached the expected number of " + | ||
"members with more than the minQuota partitions, and this member already have minQuota partitions", unfilledMember); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I put in |
||
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sense! I choose
expectedNumMembersAssignedOverMinQuota
andnumMembersAssignedOverMinQuota
. :)