|
@@ -214,54 +214,45 @@ func (s *stickyBalanceStrategy) Plan(members map[string]ConsumerGroupMemberMetad
|
|
|
}
|
|
|
|
|
|
|
|
|
- currentPartitionConsumer := make(map[topicPartitionAssignment]string, len(currentAssignment))
|
|
|
- for memberID, partitions := range currentAssignment {
|
|
|
- for _, partition := range partitions {
|
|
|
- currentPartitionConsumer[partition] = memberID
|
|
|
- }
|
|
|
+ currentPartitionConsumers := make(map[topicPartitionAssignment]string, len(currentAssignment))
|
|
|
+ unvisitedPartitions := make(map[topicPartitionAssignment][]string, len(partition2AllPotentialConsumers))
|
|
|
+ for partition := range partition2AllPotentialConsumers {
|
|
|
+ unvisitedPartitions[partition] = []string{}
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- sortedPartitions := sortPartitions(currentAssignment, prevAssignment, isFreshAssignment, partition2AllPotentialConsumers, consumer2AllPotentialPartitions)
|
|
|
- unassignedPartitions := deepCopyPartitions(sortedPartitions)
|
|
|
+ var unassignedPartitions []topicPartitionAssignment
|
|
|
for memberID, partitions := range currentAssignment {
|
|
|
-
|
|
|
- if _, exists := members[memberID]; !exists {
|
|
|
- for _, partition := range partitions {
|
|
|
- delete(currentPartitionConsumer, partition)
|
|
|
- }
|
|
|
- delete(currentAssignment, memberID)
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- updatedPartitions := deepCopyPartitions(partitions)
|
|
|
+ var keepPartitions []topicPartitionAssignment
|
|
|
for _, partition := range partitions {
|
|
|
+
|
|
|
+
|
|
|
if _, exists := partition2AllPotentialConsumers[partition]; !exists {
|
|
|
-
|
|
|
- updatedPartitions = removeTopicPartitionFromMemberAssignments(updatedPartitions, partition)
|
|
|
- delete(currentPartitionConsumer, partition)
|
|
|
- } else if _, exists := topics[partition.Topic]; !exists {
|
|
|
-
|
|
|
-
|
|
|
- updatedPartitions = removeTopicPartitionFromMemberAssignments(updatedPartitions, partition)
|
|
|
- } else {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- unassignedPartitions = removeTopicPartitionFromMemberAssignments(unassignedPartitions, partition)
|
|
|
+ continue
|
|
|
}
|
|
|
+ delete(unvisitedPartitions, partition)
|
|
|
+ currentPartitionConsumers[partition] = memberID
|
|
|
+
|
|
|
+ if !strsContains(members[memberID].Topics, partition.Topic) {
|
|
|
+ unassignedPartitions = append(unassignedPartitions, partition)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ keepPartitions = append(keepPartitions, partition)
|
|
|
}
|
|
|
- currentAssignment[memberID] = updatedPartitions
|
|
|
+ currentAssignment[memberID] = keepPartitions
|
|
|
+ }
|
|
|
+ for unvisited := range unvisitedPartitions {
|
|
|
+ unassignedPartitions = append(unassignedPartitions, unvisited)
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ sortedPartitions := sortPartitions(currentAssignment, prevAssignment, isFreshAssignment, partition2AllPotentialConsumers, consumer2AllPotentialPartitions)
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sortedCurrentSubscriptions := sortMemberIDsByPartitionAssignments(currentAssignment)
|
|
|
- s.balance(currentAssignment, prevAssignment, sortedPartitions, unassignedPartitions, sortedCurrentSubscriptions, consumer2AllPotentialPartitions, partition2AllPotentialConsumers, currentPartitionConsumer)
|
|
|
+ s.balance(currentAssignment, prevAssignment, sortedPartitions, unassignedPartitions, sortedCurrentSubscriptions, consumer2AllPotentialPartitions, partition2AllPotentialConsumers, currentPartitionConsumers)
|
|
|
|
|
|
|
|
|
plan := make(BalanceStrategyPlan, len(currentAssignment))
|
|
@@ -277,6 +268,15 @@ func (s *stickyBalanceStrategy) Plan(members map[string]ConsumerGroupMemberMetad
|
|
|
return plan, nil
|
|
|
}
|
|
|
|
|
|
+func strsContains(s []string, value string) bool {
|
|
|
+ for _, entry := range s {
|
|
|
+ if entry == value {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
func (s *stickyBalanceStrategy) balance(currentAssignment map[string][]topicPartitionAssignment, prevAssignment map[topicPartitionAssignment]consumerGenerationPair, sortedPartitions []topicPartitionAssignment, unassignedPartitions []topicPartitionAssignment, sortedCurrentSubscriptions []string, consumer2AllPotentialPartitions map[string][]topicPartitionAssignment, partition2AllPotentialConsumers map[topicPartitionAssignment][]string, currentPartitionConsumer map[topicPartitionAssignment]string) {
|
|
|
initializing := false
|
|
@@ -601,28 +601,23 @@ func sortPartitions(currentAssignment map[string][]topicPartitionAssignment, par
|
|
|
member := pq[0]
|
|
|
|
|
|
|
|
|
- var prevPartition *topicPartitionAssignment
|
|
|
var prevPartitionIndex int
|
|
|
for i, partition := range member.assignments {
|
|
|
if _, exists := partitionsWithADifferentPreviousAssignment[partition]; exists {
|
|
|
- prevPartition = &partition
|
|
|
prevPartitionIndex = i
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if prevPartition != nil {
|
|
|
-
|
|
|
- member.assignments = append(member.assignments[:prevPartitionIndex], member.assignments[prevPartitionIndex+1:]...)
|
|
|
- sortedPartitions = append(sortedPartitions, *prevPartition)
|
|
|
- delete(unassignedPartitions, *prevPartition)
|
|
|
- heap.Fix(&pq, 0)
|
|
|
- } else if len(member.assignments) > 0 {
|
|
|
-
|
|
|
- partition := member.assignments[0]
|
|
|
- member.assignments = append(member.assignments[:0], member.assignments[1:]...)
|
|
|
+ if len(member.assignments) > 0 {
|
|
|
+ partition := member.assignments[prevPartitionIndex]
|
|
|
sortedPartitions = append(sortedPartitions, partition)
|
|
|
delete(unassignedPartitions, partition)
|
|
|
+ if prevPartitionIndex == 0 {
|
|
|
+ member.assignments = member.assignments[1:]
|
|
|
+ } else {
|
|
|
+ member.assignments = append(member.assignments[:prevPartitionIndex], member.assignments[prevPartitionIndex+1:]...)
|
|
|
+ }
|
|
|
heap.Fix(&pq, 0)
|
|
|
} else {
|
|
|
heap.Pop(&pq)
|