You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							53 lines
						
					
					
						
							1.8 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							53 lines
						
					
					
						
							1.8 KiB
						
					
					
				
								package pub_balancer
							 | 
						|
								
							 | 
						|
								import (
							 | 
						|
									"math/rand/v2"
							 | 
						|
								
							 | 
						|
									cmap "github.com/orcaman/concurrent-map/v2"
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/mq/topic"
							 | 
						|
								)
							 | 
						|
								
							 | 
						|
								func BalanceTopicPartitionOnBrokers(brokers cmap.ConcurrentMap[string, *BrokerStats]) BalanceAction {
							 | 
						|
									// 1. calculate the average number of partitions per broker
							 | 
						|
									var totalPartitionCount int32
							 | 
						|
									var totalBrokerCount int32
							 | 
						|
									for brokerStats := range brokers.IterBuffered() {
							 | 
						|
										totalBrokerCount++
							 | 
						|
										totalPartitionCount += brokerStats.Val.TopicPartitionCount
							 | 
						|
									}
							 | 
						|
									averagePartitionCountPerBroker := totalPartitionCount / totalBrokerCount
							 | 
						|
									minPartitionCountPerBroker := averagePartitionCountPerBroker
							 | 
						|
									maxPartitionCountPerBroker := averagePartitionCountPerBroker
							 | 
						|
									var sourceBroker, targetBroker string
							 | 
						|
									var candidatePartition *topic.TopicPartition
							 | 
						|
									for brokerStats := range brokers.IterBuffered() {
							 | 
						|
										if minPartitionCountPerBroker > brokerStats.Val.TopicPartitionCount {
							 | 
						|
											minPartitionCountPerBroker = brokerStats.Val.TopicPartitionCount
							 | 
						|
											targetBroker = brokerStats.Key
							 | 
						|
										}
							 | 
						|
										if maxPartitionCountPerBroker < brokerStats.Val.TopicPartitionCount {
							 | 
						|
											maxPartitionCountPerBroker = brokerStats.Val.TopicPartitionCount
							 | 
						|
											sourceBroker = brokerStats.Key
							 | 
						|
											// select a random partition from the source broker
							 | 
						|
											randomPartitionIndex := rand.IntN(int(brokerStats.Val.TopicPartitionCount))
							 | 
						|
											index := 0
							 | 
						|
											for topicPartitionStats := range brokerStats.Val.TopicPartitionStats.IterBuffered() {
							 | 
						|
												if index == randomPartitionIndex {
							 | 
						|
													candidatePartition = &topicPartitionStats.Val.TopicPartition
							 | 
						|
													break
							 | 
						|
												} else {
							 | 
						|
													index++
							 | 
						|
												}
							 | 
						|
											}
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
									if minPartitionCountPerBroker >= maxPartitionCountPerBroker-1 {
							 | 
						|
										return nil
							 | 
						|
									}
							 | 
						|
									// 2. move the partitions from the source broker to the target broker
							 | 
						|
									return &BalanceActionMove{
							 | 
						|
										TopicPartition: *candidatePartition,
							 | 
						|
										SourceBroker:   sourceBroker,
							 | 
						|
										TargetBroker:   targetBroker,
							 | 
						|
									}
							 | 
						|
								}
							 |