You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jira@kafka.apache.org by "squah-confluent (via GitHub)" <gi...@apache.org> on 2025/05/11 21:48:46 UTC

[PR] KAFKA-18688: Fix uniform homogeneous assignor stability [kafka]

squah-confluent opened a new pull request, #19677:
URL: https://github.com/apache/kafka/pull/19677

   When the number of partitions is not divisible by the number of members,
   some members will end up with one more partition than others.
   Previously, we required these to be the members at the start of the
   iteration order, which meant that partitions could be reassigned even
   when the previous assignment was already balanced.
       
   Allow any member to have the extra partition, so that we do not move
   partitions around when the previous assignment is already balanced.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] KAFKA-18688: Fix uniform homogeneous assignor stability [kafka]

Posted by "dajac (via GitHub)" <gi...@apache.org>.
dajac commented on code in PR #19677:
URL: https://github.com/apache/kafka/pull/19677#discussion_r2086645708


##########
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/assignor/UniformHomogeneousAssignmentBuilder.java:
##########
@@ -152,8 +152,13 @@ public GroupAssignment build() throws PartitionAssignorException {
      * This method ensures that the original assignment is not copied if it is not
      * altered.
      */
+    @SuppressWarnings({"CyclomaticComplexity", "NPathComplexity"})

Review Comment:
   Do we still need those exceptions?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] KAFKA-18688: Fix uniform homogeneous assignor stability [kafka]

Posted by "squah-confluent (via GitHub)" <gi...@apache.org>.
squah-confluent commented on PR #19677:
URL: https://github.com/apache/kafka/pull/19677#issuecomment-2870221833

   <details>
   <summary>Benchmarks before and after</summary>
   
   Scroll right for after numbers.
   
   ```
   Benchmark: ServerSideAssignorBenchmark.doAssignment
   assignorType: UNIFORM
   isRackAware: false
   subscriptionType: HOMOGENEOUS
   
                                                                                         Before                      After
   (assignmentType)  (memberCount)  (partitionsToMemberRatio)  (topicCount)  Mode  Cnt   Score    Error  Units       Score    Error  Units
               FULL            100                          5            10  avgt    5   0.020 ±  0.001  ms/op       0.020 ±  0.001  ms/op
               FULL            100                          5           100  avgt    5   0.027 ±  0.001  ms/op       0.026 ±  0.002  ms/op
               FULL            100                          5          1000  avgt    5   0.066 ±  0.001  ms/op       0.063 ±  0.002  ms/op
               FULL            100                         10            10  avgt    5   0.030 ±  0.001  ms/op       0.033 ±  0.001  ms/op
               FULL            100                         10           100  avgt    5   0.035 ±  0.001  ms/op       0.037 ±  0.003  ms/op
               FULL            100                         10          1000  avgt    5   0.131 ±  0.005  ms/op       0.129 ±  0.003  ms/op
               FULL            100                         50            10  avgt    5   0.134 ±  0.004  ms/op       0.121 ±  0.002  ms/op
               FULL            100                         50           100  avgt    5   0.125 ±  0.002  ms/op       0.144 ±  0.003  ms/op
               FULL            100                         50          1000  avgt    5   0.205 ±  0.005  ms/op       0.193 ±  0.008  ms/op
               FULL            500                          5            10  avgt    5   0.089 ±  0.002  ms/op       0.090 ±  0.002  ms/op
               FULL            500                          5           100  avgt    5   0.108 ±  0.006  ms/op       0.101 ±  0.001  ms/op
               FULL            500                          5          1000  avgt    5   0.176 ±  0.008  ms/op       0.174 ±  0.005  ms/op
               FULL            500                         10            10  avgt    5   0.136 ±  0.003  ms/op       0.131 ±  0.002  ms/op
               FULL            500                         10           100  avgt    5   0.146 ±  0.004  ms/op       0.147 ±  0.002  ms/op
               FULL            500                         10          1000  avgt    5   0.224 ±  0.003  ms/op       0.241 ±  0.004  ms/op
               FULL            500                         50            10  avgt    5   0.668 ±  0.012  ms/op       0.699 ±  0.013  ms/op
               FULL            500                         50           100  avgt    5   0.685 ±  0.018  ms/op       0.696 ±  0.024  ms/op
               FULL            500                         50          1000  avgt    5   0.773 ±  0.021  ms/op       0.958 ±  0.028  ms/op
               FULL           1000                          5            10  avgt    5   0.179 ±  0.004  ms/op       0.168 ±  0.004  ms/op
               FULL           1000                          5           100  avgt    5   0.196 ±  0.002  ms/op       0.191 ±  0.004  ms/op
               FULL           1000                          5          1000  avgt    5   0.261 ±  0.006  ms/op       0.312 ±  0.004  ms/op
               FULL           1000                         10            10  avgt    5   0.288 ±  0.007  ms/op       0.264 ±  0.005  ms/op
               FULL           1000                         10           100  avgt    5   0.290 ±  0.012  ms/op       0.310 ±  0.055  ms/op
               FULL           1000                         10          1000  avgt    5   0.412 ±  0.004  ms/op       0.420 ±  0.012  ms/op
               FULL           1000                         50            10  avgt    5   1.261 ±  0.032  ms/op       1.264 ±  0.026  ms/op
               FULL           1000                         50           100  avgt    5   1.291 ±  0.036  ms/op       1.399 ±  0.057  ms/op
               FULL           1000                         50          1000  avgt    5   1.225 ±  0.038  ms/op       1.454 ±  0.035  ms/op
               FULL           5000                          5            10  avgt    5   1.090 ±  0.042  ms/op       0.878 ±  0.021  ms/op
               FULL           5000                          5           100  avgt    5   1.077 ±  0.045  ms/op       1.023 ±  0.020  ms/op
               FULL           5000                          5          1000  avgt    5   1.163 ±  0.016  ms/op       1.100 ±  0.017  ms/op
               FULL           5000                         10            10  avgt    5   1.371 ±  0.029  ms/op       1.334 ±  0.017  ms/op
               FULL           5000                         10           100  avgt    5   1.478 ±  0.040  ms/op       1.526 ±  0.038  ms/op
               FULL           5000                         10          1000  avgt    5   1.602 ±  0.057  ms/op       1.790 ±  0.046  ms/op
               FULL           5000                         50            10  avgt    5   5.869 ±  0.202  ms/op       5.975 ±  0.184  ms/op
               FULL           5000                         50           100  avgt    5   6.367 ±  0.266  ms/op       6.016 ±  0.180  ms/op
               FULL           5000                         50          1000  avgt    5   6.918 ±  0.184  ms/op       7.641 ±  1.245  ms/op
               FULL          10000                          5            10  avgt    5   1.780 ±  0.040  ms/op       1.725 ±  0.023  ms/op
               FULL          10000                          5           100  avgt    5   1.862 ±  0.051  ms/op       1.809 ±  0.028  ms/op
               FULL          10000                          5          1000  avgt    5   2.238 ±  0.060  ms/op       2.037 ±  0.097  ms/op
               FULL          10000                         10            10  avgt    5   2.864 ±  0.071  ms/op       2.602 ±  0.119  ms/op
               FULL          10000                         10           100  avgt    5   2.903 ±  0.110  ms/op       2.884 ±  0.242  ms/op
               FULL          10000                         10          1000  avgt    5   3.274 ±  0.143  ms/op       3.158 ±  0.193  ms/op
               FULL          10000                         50            10  avgt    5  12.125 ±  0.521  ms/op      13.874 ±  0.674  ms/op
               FULL          10000                         50           100  avgt    5  13.244 ±  0.677  ms/op      12.351 ±  0.465  ms/op
               FULL          10000                         50          1000  avgt    5  13.840 ±  1.825  ms/op      14.557 ±  0.745  ms/op
        INCREMENTAL            100                          5            10  avgt    5   0.010 ±  0.001  ms/op       0.010 ±  0.001  ms/op
        INCREMENTAL            100                          5           100  avgt    5   0.018 ±  0.003  ms/op       0.017 ±  0.001  ms/op
        INCREMENTAL            100                          5          1000  avgt    5   0.062 ±  0.001  ms/op       0.068 ±  0.001  ms/op
        INCREMENTAL            100                         10            10  avgt    5   0.015 ±  0.001  ms/op       0.015 ±  0.001  ms/op
        INCREMENTAL            100                         10           100  avgt    5   0.026 ±  0.001  ms/op       0.023 ±  0.001  ms/op
        INCREMENTAL            100                         10          1000  avgt    5   0.102 ±  0.002  ms/op       0.106 ±  0.002  ms/op
        INCREMENTAL            100                         50            10  avgt    5   0.098 ±  0.008  ms/op       0.087 ±  0.001  ms/op
        INCREMENTAL            100                         50           100  avgt    5   0.093 ±  0.002  ms/op       0.093 ±  0.002  ms/op
        INCREMENTAL            100                         50          1000  avgt    5   0.195 ±  0.004  ms/op       0.196 ±  0.004  ms/op
        INCREMENTAL            500                          5            10  avgt    5   0.049 ±  0.001  ms/op       0.052 ±  0.001  ms/op
        INCREMENTAL            500                          5           100  avgt    5   0.062 ±  0.001  ms/op       0.061 ±  0.001  ms/op
        INCREMENTAL            500                          5          1000  avgt    5   0.135 ±  0.005  ms/op       0.140 ±  0.003  ms/op
        INCREMENTAL            500                         10            10  avgt    5   0.062 ±  0.002  ms/op       0.059 ±  0.001  ms/op
        INCREMENTAL            500                         10           100  avgt    5   0.067 ±  0.001  ms/op       0.068 ±  0.002  ms/op
        INCREMENTAL            500                         10          1000  avgt    5   0.156 ±  0.003  ms/op       0.159 ±  0.007  ms/op
        INCREMENTAL            500                         50            10  avgt    5   0.194 ±  0.004  ms/op       0.211 ±  0.003  ms/op
        INCREMENTAL            500                         50           100  avgt    5   0.213 ±  0.006  ms/op       0.218 ±  0.002  ms/op
        INCREMENTAL            500                         50          1000  avgt    5   0.343 ±  0.010  ms/op       0.304 ±  0.005  ms/op
        INCREMENTAL           1000                          5            10  avgt    5   0.088 ±  0.002  ms/op       0.089 ±  0.001  ms/op
        INCREMENTAL           1000                          5           100  avgt    5   0.097 ±  0.002  ms/op       0.095 ±  0.002  ms/op
        INCREMENTAL           1000                          5          1000  avgt    5   0.184 ±  0.006  ms/op       0.194 ±  0.004  ms/op
        INCREMENTAL           1000                         10            10  avgt    5   0.108 ±  0.002  ms/op       0.123 ±  0.003  ms/op
        INCREMENTAL           1000                         10           100  avgt    5   0.132 ±  0.002  ms/op       0.129 ±  0.003  ms/op
        INCREMENTAL           1000                         10          1000  avgt    5   0.224 ±  0.004  ms/op       0.229 ±  0.004  ms/op
        INCREMENTAL           1000                         50            10  avgt    5   0.339 ±  0.012  ms/op       0.382 ±  0.008  ms/op
        INCREMENTAL           1000                         50           100  avgt    5   0.346 ±  0.007  ms/op       0.348 ±  0.004  ms/op
        INCREMENTAL           1000                         50          1000  avgt    5   0.458 ±  0.012  ms/op       0.481 ±  0.011  ms/op
        INCREMENTAL           5000                          5            10  avgt    5   0.455 ±  0.013  ms/op       0.496 ±  0.009  ms/op
        INCREMENTAL           5000                          5           100  avgt    5   0.471 ±  0.009  ms/op       0.495 ±  0.011  ms/op
        INCREMENTAL           5000                          5          1000  avgt    5   0.587 ±  0.011  ms/op       0.579 ±  0.014  ms/op
        INCREMENTAL           5000                         10            10  avgt    5   0.488 ±  0.008  ms/op       0.608 ±  0.048  ms/op
        INCREMENTAL           5000                         10           100  avgt    5   0.537 ±  0.006  ms/op       0.514 ±  0.013  ms/op
        INCREMENTAL           5000                         10          1000  avgt    5   0.705 ±  0.020  ms/op       0.752 ±  0.044  ms/op
        INCREMENTAL           5000                         50            10  avgt    5   1.586 ±  0.076  ms/op       1.619 ±  0.066  ms/op
        INCREMENTAL           5000                         50           100  avgt    5   1.809 ±  0.207  ms/op       1.725 ±  0.197  ms/op
        INCREMENTAL           5000                         50          1000  avgt    5   1.875 ±  0.222  ms/op       1.885 ±  0.158  ms/op
        INCREMENTAL          10000                          5            10  avgt    5   0.824 ±  0.035  ms/op       0.704 ±  0.027  ms/op
        INCREMENTAL          10000                          5           100  avgt    5   0.904 ±  0.092  ms/op       0.881 ±  0.039  ms/op
        INCREMENTAL          10000                          5          1000  avgt    5   1.076 ±  0.049  ms/op       1.071 ±  0.073  ms/op
        INCREMENTAL          10000                         10            10  avgt    5   0.968 ±  0.054  ms/op       1.041 ±  0.053  ms/op
        INCREMENTAL          10000                         10           100  avgt    5   1.288 ±  0.064  ms/op       1.112 ±  0.076  ms/op
        INCREMENTAL          10000                         10          1000  avgt    5   1.358 ±  0.051  ms/op       1.374 ±  0.084  ms/op
        INCREMENTAL          10000                         50            10  avgt    5   3.064 ±  0.435  ms/op       3.124 ±  0.276  ms/op
        INCREMENTAL          10000                         50           100  avgt    5   3.479 ±  0.576  ms/op       3.428 ±  0.244  ms/op
        INCREMENTAL          10000                         50          1000  avgt    5   4.418 ±  0.735  ms/op       4.377 ±  0.629  ms/op
   ```
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] KAFKA-18688: Fix uniform homogeneous assignor stability [kafka]

Posted by "dajac (via GitHub)" <gi...@apache.org>.
dajac commented on code in PR #19677:
URL: https://github.com/apache/kafka/pull/19677#discussion_r2086647061


##########
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/assignor/UniformHomogeneousAssignmentBuilder.java:
##########
@@ -218,6 +234,15 @@ private void maybeRevokePartitions() {
                 targetAssignment.put(memberId, new MemberAssignmentImpl(newAssignment));
             }
         }
+
+        // Distribute the remaining extra partitions to the members that are at or under the minimum
+        // quota. When there are remaining extra partitions, we can't run out of unfilledMembers
+        // here because all members either subtracted from remainingMembersToGetAnExtraPartition or
+        // went into the unfilledMembers list.
+        for (int i = 0; i < remainingMembersToGetAnExtraPartition; i++) {
+            unfilledMembers.get(i).remainingQuota++;
+        }
+        remainingMembersToGetAnExtraPartition = 0;

Review Comment:
   Could you please put the results in the description too?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] KAFKA-18688: Fix uniform homogeneous assignor stability [kafka]

Posted by "squah-confluent (via GitHub)" <gi...@apache.org>.
squah-confluent commented on code in PR #19677:
URL: https://github.com/apache/kafka/pull/19677#discussion_r2086378831


##########
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/assignor/UniformHomogeneousAssignmentBuilder.java:
##########
@@ -218,6 +234,15 @@ private void maybeRevokePartitions() {
                 targetAssignment.put(memberId, new MemberAssignmentImpl(newAssignment));
             }
         }
+
+        // Distribute the remaining extra partitions to the members that are at or under the minimum
+        // quota. When there are remaining extra partitions, we can't run out of unfilledMembers
+        // here because all members either subtracted from remainingMembersToGetAnExtraPartition or
+        // went into the unfilledMembers list.
+        for (int i = 0; i < remainingMembersToGetAnExtraPartition; i++) {
+            unfilledMembers.get(i).remainingQuota++;
+        }
+        remainingMembersToGetAnExtraPartition = 0;

Review Comment:
   Thanks for reviewing. I like this suggestion, I think it may be a bit cleaner and we can make it work.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] KAFKA-18688: Fix uniform homogeneous assignor stability [kafka]

Posted by "squah-confluent (via GitHub)" <gi...@apache.org>.
squah-confluent commented on code in PR #19677:
URL: https://github.com/apache/kafka/pull/19677#discussion_r2086658896


##########
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/assignor/UniformHomogeneousAssignmentBuilder.java:
##########
@@ -152,8 +152,13 @@ public GroupAssignment build() throws PartitionAssignorException {
      * This method ensures that the original assignment is not copied if it is not
      * altered.
      */
+    @SuppressWarnings({"CyclomaticComplexity", "NPathComplexity"})

Review Comment:
   I tried removing them and we're still just slightly above the threshold.



##########
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/assignor/UniformHomogeneousAssignmentBuilder.java:
##########
@@ -152,8 +152,13 @@ public GroupAssignment build() throws PartitionAssignorException {
      * This method ensures that the original assignment is not copied if it is not
      * altered.
      */
+    @SuppressWarnings({"CyclomaticComplexity", "NPathComplexity"})

Review Comment:
   I tried removing them after the latest change and we're still just slightly above the threshold.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] KAFKA-18688: Fix uniform homogeneous assignor stability [kafka]

Posted by "dajac (via GitHub)" <gi...@apache.org>.
dajac commented on PR #19677:
URL: https://github.com/apache/kafka/pull/19677#issuecomment-2876898370

   Merged to trunk and 4.0.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] KAFKA-18688: Fix uniform homogeneous assignor stability [kafka]

Posted by "dajac (via GitHub)" <gi...@apache.org>.
dajac merged PR #19677:
URL: https://github.com/apache/kafka/pull/19677


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] KAFKA-18688: Fix uniform homogeneous assignor stability [kafka]

Posted by "squah-confluent (via GitHub)" <gi...@apache.org>.
squah-confluent commented on code in PR #19677:
URL: https://github.com/apache/kafka/pull/19677#discussion_r2086619092


##########
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/assignor/UniformHomogeneousAssignmentBuilder.java:
##########
@@ -218,6 +234,15 @@ private void maybeRevokePartitions() {
                 targetAssignment.put(memberId, new MemberAssignmentImpl(newAssignment));
             }
         }
+
+        // Distribute the remaining extra partitions to the members that are at or under the minimum
+        // quota. When there are remaining extra partitions, we can't run out of unfilledMembers
+        // here because all members either subtracted from remainingMembersToGetAnExtraPartition or
+        // went into the unfilledMembers list.
+        for (int i = 0; i < remainingMembersToGetAnExtraPartition; i++) {
+            unfilledMembers.get(i).remainingQuota++;
+        }
+        remainingMembersToGetAnExtraPartition = 0;

Review Comment:
   Updated the PR and it looks a lot cleaner.
   
   It doesn't look like there's a noticeable performance impact.
   Before the PR
   ```
   Benchmark                                 (assignmentType)  (assignorType)  (isRackAware)  (memberCount)  (partitionsToMemberRatio)  (subscriptionType)  (topicCount)  Mode  Cnt    Score   Error  Units
   ServerSideAssignorBenchmark.doAssignment              FULL           RANGE          false          10000                         50         HOMOGENEOUS          1000  avgt    2   26.175          ms/op
   ServerSideAssignorBenchmark.doAssignment              FULL           RANGE          false          10000                         50       HETEROGENEOUS          1000  avgt    2  123.955          ms/op
   ServerSideAssignorBenchmark.doAssignment       INCREMENTAL           RANGE          false          10000                         50         HOMOGENEOUS          1000  avgt    2   24.408          ms/op
   ServerSideAssignorBenchmark.doAssignment       INCREMENTAL           RANGE          false          10000                         50       HETEROGENEOUS          1000  avgt    2  114.873          ms/op
   ```
   After the PR
   ```
   Benchmark                                 (assignmentType)  (assignorType)  (isRackAware)  (memberCount)  (partitionsToMemberRatio)  (subscriptionType)  (topicCount)  Mode  Cnt    Score   Error  Units
   ServerSideAssignorBenchmark.doAssignment              FULL           RANGE          false          10000                         50         HOMOGENEOUS          1000  avgt    2   24.259          ms/op
   ServerSideAssignorBenchmark.doAssignment              FULL           RANGE          false          10000                         50       HETEROGENEOUS          1000  avgt    2  118.513          ms/op
   ServerSideAssignorBenchmark.doAssignment       INCREMENTAL           RANGE          false          10000                         50         HOMOGENEOUS          1000  avgt    2   24.636          ms/op
   ServerSideAssignorBenchmark.doAssignment       INCREMENTAL           RANGE          false          10000                         50       HETEROGENEOUS          1000  avgt    2  115.503          ms/op
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] KAFKA-18688: Fix uniform homogeneous assignor stability [kafka]

Posted by "squah-confluent (via GitHub)" <gi...@apache.org>.
squah-confluent commented on code in PR #19677:
URL: https://github.com/apache/kafka/pull/19677#discussion_r2086658896


##########
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/assignor/UniformHomogeneousAssignmentBuilder.java:
##########
@@ -152,8 +152,13 @@ public GroupAssignment build() throws PartitionAssignorException {
      * This method ensures that the original assignment is not copied if it is not
      * altered.
      */
+    @SuppressWarnings({"CyclomaticComplexity", "NPathComplexity"})

Review Comment:
   I tried removing them after the latest update and we're still just slightly above the threshold.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] KAFKA-18688: Fix uniform homogeneous assignor stability [kafka]

Posted by "dajac (via GitHub)" <gi...@apache.org>.
dajac commented on code in PR #19677:
URL: https://github.com/apache/kafka/pull/19677#discussion_r2086234212


##########
group-coordinator/src/main/java/org/apache/kafka/coordinator/group/assignor/UniformHomogeneousAssignmentBuilder.java:
##########
@@ -218,6 +234,15 @@ private void maybeRevokePartitions() {
                 targetAssignment.put(memberId, new MemberAssignmentImpl(newAssignment));
             }
         }
+
+        // Distribute the remaining extra partitions to the members that are at or under the minimum
+        // quota. When there are remaining extra partitions, we can't run out of unfilledMembers
+        // here because all members either subtracted from remainingMembersToGetAnExtraPartition or
+        // went into the unfilledMembers list.
+        for (int i = 0; i < remainingMembersToGetAnExtraPartition; i++) {
+            unfilledMembers.get(i).remainingQuota++;
+        }
+        remainingMembersToGetAnExtraPartition = 0;

Review Comment:
   I think that we could avoid this extra loop. Let's say that we track the index of the current member while we iterate on the memberIds. When the memberIds.size() - index <= remainingMembersToGetAnExtraPartition, we know that we must keep the remaining members with the adjusted quota. The idea is to basically put extra partitions at the end, unless that have been taken during the iteration. Would something like this work? I am not sure if it is really simpler than your current solution though. The benefit is that we would not need the `(remainingQuota == 0)` condition during the assignment and we could keep `MemberWithRemainingQuota` with final attributes.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org