mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 18:24:07 +00:00
Merge pull request #78009 from hainesc/develop
Use reservoir sampling to select one host from priority list
This commit is contained in:
commit
ac1cde5577
@ -20,6 +20,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"math/rand"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -160,7 +161,6 @@ type genericScheduler struct {
|
|||||||
prioritizers []priorities.PriorityConfig
|
prioritizers []priorities.PriorityConfig
|
||||||
framework framework.Framework
|
framework framework.Framework
|
||||||
extenders []algorithm.SchedulerExtender
|
extenders []algorithm.SchedulerExtender
|
||||||
lastNodeIndex uint64
|
|
||||||
alwaysCheckAllPredicates bool
|
alwaysCheckAllPredicates bool
|
||||||
nodeInfoSnapshot *internalcache.NodeInfoSnapshot
|
nodeInfoSnapshot *internalcache.NodeInfoSnapshot
|
||||||
volumeBinder *volumebinder.VolumeBinder
|
volumeBinder *volumebinder.VolumeBinder
|
||||||
@ -271,34 +271,29 @@ func (g *genericScheduler) Predicates() map[string]predicates.FitPredicate {
|
|||||||
return g.predicates
|
return g.predicates
|
||||||
}
|
}
|
||||||
|
|
||||||
// findMaxScores returns the indexes of nodes in the "priorityList" that has the highest "Score".
|
|
||||||
func findMaxScores(priorityList schedulerapi.HostPriorityList) []int {
|
|
||||||
maxScoreIndexes := make([]int, 0, len(priorityList)/2)
|
|
||||||
maxScore := priorityList[0].Score
|
|
||||||
for i, hp := range priorityList {
|
|
||||||
if hp.Score > maxScore {
|
|
||||||
maxScore = hp.Score
|
|
||||||
maxScoreIndexes = maxScoreIndexes[:0]
|
|
||||||
maxScoreIndexes = append(maxScoreIndexes, i)
|
|
||||||
} else if hp.Score == maxScore {
|
|
||||||
maxScoreIndexes = append(maxScoreIndexes, i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return maxScoreIndexes
|
|
||||||
}
|
|
||||||
|
|
||||||
// selectHost takes a prioritized list of nodes and then picks one
|
// selectHost takes a prioritized list of nodes and then picks one
|
||||||
// in a round-robin manner from the nodes that had the highest score.
|
// in a reservoir sampling manner from the nodes that had the highest score.
|
||||||
func (g *genericScheduler) selectHost(priorityList schedulerapi.HostPriorityList) (string, error) {
|
func (g *genericScheduler) selectHost(priorityList schedulerapi.HostPriorityList) (string, error) {
|
||||||
if len(priorityList) == 0 {
|
if len(priorityList) == 0 {
|
||||||
return "", fmt.Errorf("empty priorityList")
|
return "", fmt.Errorf("empty priorityList")
|
||||||
}
|
}
|
||||||
|
maxScore := priorityList[0].Score
|
||||||
maxScores := findMaxScores(priorityList)
|
selected := priorityList[0].Host
|
||||||
ix := int(g.lastNodeIndex % uint64(len(maxScores)))
|
cntOfMaxScore := 1
|
||||||
g.lastNodeIndex++
|
for _, hp := range priorityList[1:] {
|
||||||
|
if hp.Score > maxScore {
|
||||||
return priorityList[maxScores[ix]].Host, nil
|
maxScore = hp.Score
|
||||||
|
selected = hp.Host
|
||||||
|
cntOfMaxScore = 1
|
||||||
|
} else if hp.Score == maxScore {
|
||||||
|
cntOfMaxScore++
|
||||||
|
if rand.Intn(cntOfMaxScore) == 0 {
|
||||||
|
// Replace the candidate with probability of 1/cntOfMaxScore
|
||||||
|
selected = hp.Host
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selected, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// preempt finds nodes with pods that can be preempted to make room for "pod" to
|
// preempt finds nodes with pods that can be preempted to make room for "pod" to
|
||||||
|
Loading…
Reference in New Issue
Block a user