Пример #1
0
// Moves a single partition from the largest entry to the smallest.  only
// if the smallest entry is smaller then the rest.
// if all entries are the same size, then a random entry is chosen
func RebalanceSingle(services *Services, routerTable *shards.RouterTable) error {

	var smallest *shards.RouterEntry = nil
	var largest *shards.RouterEntry = nil

	min := int(routerTable.TotalPartitions / len(routerTable.Entries))
	services.Logger.Printf("Looking for entries with more then %d partitions", min)

	//shuffle the entries array
	entries := make([]*shards.RouterEntry, len(routerTable.Entries))
	perm := rand.Perm(len(routerTable.Entries))
	for i, v := range perm {
		entries[v] = routerTable.Entries[i]
	}

	for _, entry := range entries {
		if len(entry.Partitions) < min {
			if smallest == nil {
				smallest = entry
			} else if len(entry.Partitions) < len(smallest.Partitions) {
				smallest = entry
			}

			if largest == nil {
				largest = entry
			} else if len(entry.Partitions) > len(largest.Partitions) {
				largest = entry
			}
		}
	}
	if smallest == nil || largest == nil {
		services.Logger.Printf("Cluster appears to be balanced")
		return nil
	}

	services.Logger.Printf("Moving from %s to %s", largest.Id(), smallest.Id())

	return nil
}