mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 10:51:29 +00:00
Merge pull request #89665 from alculquicondor/per_node_filter_spreading
Optimize topology spreading filter
This commit is contained in:
commit
dda530cfb7
@ -20,12 +20,12 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/klog"
|
||||
pluginhelper "k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper"
|
||||
framework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
|
||||
"k8s.io/kubernetes/pkg/scheduler/internal/parallelize"
|
||||
"k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
||||
@ -48,7 +48,7 @@ type preFilterState struct {
|
||||
// it's not guaranteed to be the 2nd minimum match number.
|
||||
TpKeyToCriticalPaths map[string]*criticalPaths
|
||||
// TpPairToMatchNum is keyed with topologyPair, and valued with the number of matching pods.
|
||||
TpPairToMatchNum map[topologyPair]int32
|
||||
TpPairToMatchNum map[topologyPair]*int32
|
||||
}
|
||||
|
||||
// Clone makes a copy of the given state.
|
||||
@ -61,14 +61,15 @@ func (s *preFilterState) Clone() framework.StateData {
|
||||
// Constraints are shared because they don't change.
|
||||
Constraints: s.Constraints,
|
||||
TpKeyToCriticalPaths: make(map[string]*criticalPaths, len(s.TpKeyToCriticalPaths)),
|
||||
TpPairToMatchNum: make(map[topologyPair]int32, len(s.TpPairToMatchNum)),
|
||||
TpPairToMatchNum: make(map[topologyPair]*int32, len(s.TpPairToMatchNum)),
|
||||
}
|
||||
for tpKey, paths := range s.TpKeyToCriticalPaths {
|
||||
copy.TpKeyToCriticalPaths[tpKey] = &criticalPaths{paths[0], paths[1]}
|
||||
}
|
||||
for tpPair, matchNum := range s.TpPairToMatchNum {
|
||||
copyPair := topologyPair{key: tpPair.key, value: tpPair.value}
|
||||
copy.TpPairToMatchNum[copyPair] = matchNum
|
||||
copyCount := *matchNum
|
||||
copy.TpPairToMatchNum[copyPair] = ©Count
|
||||
}
|
||||
return ©
|
||||
}
|
||||
@ -137,9 +138,9 @@ func (s *preFilterState) updateWithPod(updatedPod, preemptorPod *v1.Pod, node *v
|
||||
|
||||
k, v := constraint.TopologyKey, node.Labels[constraint.TopologyKey]
|
||||
pair := topologyPair{key: k, value: v}
|
||||
s.TpPairToMatchNum[pair] = s.TpPairToMatchNum[pair] + delta
|
||||
*s.TpPairToMatchNum[pair] += delta
|
||||
|
||||
s.TpKeyToCriticalPaths[k].update(v, s.TpPairToMatchNum[pair])
|
||||
s.TpKeyToCriticalPaths[k].update(v, *s.TpPairToMatchNum[pair])
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,52 +220,44 @@ func (pl *PodTopologySpread) calPreFilterState(pod *v1.Pod) (*preFilterState, er
|
||||
return &preFilterState{}, nil
|
||||
}
|
||||
|
||||
var lock sync.Mutex
|
||||
|
||||
// TODO(Huang-Wei): It might be possible to use "make(map[topologyPair]*int32)".
|
||||
// In that case, need to consider how to init each tpPairToCount[pair] in an atomic fashion.
|
||||
s := preFilterState{
|
||||
Constraints: constraints,
|
||||
TpKeyToCriticalPaths: make(map[string]*criticalPaths, len(constraints)),
|
||||
TpPairToMatchNum: make(map[topologyPair]int32),
|
||||
TpPairToMatchNum: make(map[topologyPair]*int32, sizeHeuristic(len(allNodes), constraints)),
|
||||
}
|
||||
for _, n := range allNodes {
|
||||
node := n.Node()
|
||||
if node == nil {
|
||||
klog.Error("node not found")
|
||||
continue
|
||||
}
|
||||
// In accordance to design, if NodeAffinity or NodeSelector is defined,
|
||||
// spreading is applied to nodes that pass those filters.
|
||||
if !helper.PodMatchesNodeSelectorAndAffinityTerms(pod, node) {
|
||||
continue
|
||||
}
|
||||
// Ensure current node's labels contains all topologyKeys in 'Constraints'.
|
||||
if !nodeLabelsMatchSpreadConstraints(node.Labels, constraints) {
|
||||
continue
|
||||
}
|
||||
for _, c := range constraints {
|
||||
pair := topologyPair{key: c.TopologyKey, value: node.Labels[c.TopologyKey]}
|
||||
s.TpPairToMatchNum[pair] = new(int32)
|
||||
}
|
||||
addTopologyPairMatchNum := func(pair topologyPair, num int32) {
|
||||
lock.Lock()
|
||||
s.TpPairToMatchNum[pair] += num
|
||||
lock.Unlock()
|
||||
}
|
||||
|
||||
processNode := func(i int) {
|
||||
nodeInfo := allNodes[i]
|
||||
node := nodeInfo.Node()
|
||||
if node == nil {
|
||||
klog.Error("node not found")
|
||||
return
|
||||
}
|
||||
// In accordance to design, if NodeAffinity or NodeSelector is defined,
|
||||
// spreading is applied to nodes that pass those filters.
|
||||
if !pluginhelper.PodMatchesNodeSelectorAndAffinityTerms(pod, node) {
|
||||
return
|
||||
}
|
||||
|
||||
// Ensure current node's labels contains all topologyKeys in 'Constraints'.
|
||||
if !nodeLabelsMatchSpreadConstraints(node.Labels, constraints) {
|
||||
return
|
||||
}
|
||||
for _, constraint := range constraints {
|
||||
matchTotal := int32(0)
|
||||
// nodeInfo.Pods() can be empty; or all pods don't fit
|
||||
for _, existingPod := range nodeInfo.Pods() {
|
||||
// Bypass terminating Pod (see #87621).
|
||||
if existingPod.DeletionTimestamp != nil || existingPod.Namespace != pod.Namespace {
|
||||
pair := topologyPair{key: constraint.TopologyKey, value: node.Labels[constraint.TopologyKey]}
|
||||
tpCount := s.TpPairToMatchNum[pair]
|
||||
if tpCount == nil {
|
||||
continue
|
||||
}
|
||||
if constraint.Selector.Matches(labels.Set(existingPod.Labels)) {
|
||||
matchTotal++
|
||||
}
|
||||
}
|
||||
pair := topologyPair{key: constraint.TopologyKey, value: node.Labels[constraint.TopologyKey]}
|
||||
addTopologyPairMatchNum(pair, matchTotal)
|
||||
count := countPodsMatchSelector(nodeInfo.Pods(), constraint.Selector, pod.Namespace)
|
||||
atomic.AddInt32(tpCount, int32(count))
|
||||
}
|
||||
}
|
||||
parallelize.Until(context.Background(), len(allNodes), processNode)
|
||||
@ -275,7 +268,7 @@ func (pl *PodTopologySpread) calPreFilterState(pod *v1.Pod) (*preFilterState, er
|
||||
s.TpKeyToCriticalPaths[key] = newCriticalPaths()
|
||||
}
|
||||
for pair, num := range s.TpPairToMatchNum {
|
||||
s.TpKeyToCriticalPaths[pair.key].update(pair.value, num)
|
||||
s.TpKeyToCriticalPaths[pair.key].update(pair.value, *num)
|
||||
}
|
||||
|
||||
return &s, nil
|
||||
@ -322,7 +315,10 @@ func (pl *PodTopologySpread) Filter(ctx context.Context, cycleState *framework.C
|
||||
// judging criteria:
|
||||
// 'existing matching num' + 'if self-match (1 or 0)' - 'global min matching num' <= 'maxSkew'
|
||||
minMatchNum := paths[0].MatchNum
|
||||
matchNum := s.TpPairToMatchNum[pair]
|
||||
matchNum := int32(0)
|
||||
if tpCount := s.TpPairToMatchNum[pair]; tpCount != nil {
|
||||
matchNum = *tpCount
|
||||
}
|
||||
skew := matchNum + selfMatchNum - minMatchNum
|
||||
if skew > c.MaxSkew {
|
||||
klog.V(5).Infof("node '%s' failed spreadConstraint[%s]: MatchNum(%d) + selfMatchNum(%d) - minMatchNum(%d) > maxSkew(%d)", node.Name, tpKey, matchNum, selfMatchNum, minMatchNum, c.MaxSkew)
|
||||
@ -332,3 +328,12 @@ func (pl *PodTopologySpread) Filter(ctx context.Context, cycleState *framework.C
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func sizeHeuristic(nodes int, constraints []topologySpreadConstraint) int {
|
||||
for _, c := range constraints {
|
||||
if c.TopologyKey == v1.LabelHostname {
|
||||
return nodes
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
@ -30,8 +30,10 @@ import (
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
framework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
|
||||
"k8s.io/kubernetes/pkg/scheduler/internal/cache"
|
||||
"k8s.io/kubernetes/pkg/scheduler/internal/parallelize"
|
||||
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
||||
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
var cmpOpts = []cmp.Option{
|
||||
@ -86,9 +88,9 @@ func TestPreFilterState(t *testing.T) {
|
||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||
"zone": {{"zone1", 0}, {"zone2", 0}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 0,
|
||||
{key: "zone", value: "zone2"}: 0,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(0),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -121,9 +123,9 @@ func TestPreFilterState(t *testing.T) {
|
||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||
"zone": {{"zone2", 2}, {"zone1", 3}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 3,
|
||||
{key: "zone", value: "zone2"}: 2,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(2),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -158,10 +160,10 @@ func TestPreFilterState(t *testing.T) {
|
||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||
"zone": {{"zone3", 0}, {"zone2", 2}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 3,
|
||||
{key: "zone", value: "zone2"}: 2,
|
||||
{key: "zone", value: "zone3"}: 0,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(2),
|
||||
{key: "zone", value: "zone3"}: pointer.Int32Ptr(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -194,9 +196,9 @@ func TestPreFilterState(t *testing.T) {
|
||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||
"zone": {{"zone2", 1}, {"zone1", 2}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 2,
|
||||
{key: "zone", value: "zone2"}: 1,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(2),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -238,13 +240,13 @@ func TestPreFilterState(t *testing.T) {
|
||||
"zone": {{"zone1", 3}, {"zone2", 4}},
|
||||
"node": {{"node-x", 0}, {"node-b", 1}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 3,
|
||||
{key: "zone", value: "zone2"}: 4,
|
||||
{key: "node", value: "node-a"}: 2,
|
||||
{key: "node", value: "node-b"}: 1,
|
||||
{key: "node", value: "node-x"}: 0,
|
||||
{key: "node", value: "node-y"}: 4,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(4),
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(2),
|
||||
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-x"}: pointer.Int32Ptr(0),
|
||||
{key: "node", value: "node-y"}: pointer.Int32Ptr(4),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -287,12 +289,12 @@ func TestPreFilterState(t *testing.T) {
|
||||
"zone": {{"zone1", 3}, {"zone2", 4}},
|
||||
"node": {{"node-b", 1}, {"node-a", 2}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 3,
|
||||
{key: "zone", value: "zone2"}: 4,
|
||||
{key: "node", value: "node-a"}: 2,
|
||||
{key: "node", value: "node-b"}: 1,
|
||||
{key: "node", value: "node-y"}: 4,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(4),
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(2),
|
||||
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-y"}: pointer.Int32Ptr(4),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -328,12 +330,12 @@ func TestPreFilterState(t *testing.T) {
|
||||
"zone": {{"zone2", 0}, {"zone1", 1}},
|
||||
"node": {{"node-a", 0}, {"node-y", 0}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 1,
|
||||
{key: "zone", value: "zone2"}: 0,
|
||||
{key: "node", value: "node-a"}: 0,
|
||||
{key: "node", value: "node-b"}: 1,
|
||||
{key: "node", value: "node-y"}: 0,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(1),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(0),
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(0),
|
||||
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-y"}: pointer.Int32Ptr(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -374,12 +376,12 @@ func TestPreFilterState(t *testing.T) {
|
||||
"zone": {{"zone1", 3}, {"zone2", 4}},
|
||||
"node": {{"node-b", 0}, {"node-a", 1}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 3,
|
||||
{key: "zone", value: "zone2"}: 4,
|
||||
{key: "node", value: "node-a"}: 1,
|
||||
{key: "node", value: "node-b"}: 0,
|
||||
{key: "node", value: "node-y"}: 2,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(4),
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-b"}: pointer.Int32Ptr(0),
|
||||
{key: "node", value: "node-y"}: pointer.Int32Ptr(2),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -422,12 +424,12 @@ func TestPreFilterState(t *testing.T) {
|
||||
"zone": {{"zone1", 3}, {"zone2", 4}},
|
||||
"node": {{"node-b", 1}, {"node-a", 2}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 3,
|
||||
{key: "zone", value: "zone2"}: 4,
|
||||
{key: "node", value: "node-a"}: 2,
|
||||
{key: "node", value: "node-b"}: 1,
|
||||
{key: "node", value: "node-y"}: 4,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(4),
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(2),
|
||||
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-y"}: pointer.Int32Ptr(4),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -459,7 +461,7 @@ func TestPreFilterState(t *testing.T) {
|
||||
"node": newCriticalPaths(),
|
||||
"rack": newCriticalPaths(),
|
||||
},
|
||||
TpPairToMatchNum: make(map[topologyPair]int32),
|
||||
TpPairToMatchNum: make(map[topologyPair]*int32),
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -495,7 +497,7 @@ func TestPreFilterState(t *testing.T) {
|
||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||
"zone": newCriticalPaths(),
|
||||
},
|
||||
TpPairToMatchNum: make(map[topologyPair]int32),
|
||||
TpPairToMatchNum: make(map[topologyPair]*int32),
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -572,9 +574,9 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||
"node": {{"node-b", 0}, {"node-a", 1}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "node", value: "node-a"}: 1,
|
||||
{key: "node", value: "node-b"}: 0,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-b"}: pointer.Int32Ptr(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -597,9 +599,9 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||
"node": {{"node-a", 1}, {"node-b", 1}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "node", value: "node-a"}: 1,
|
||||
{key: "node", value: "node-b"}: 1,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -622,9 +624,9 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||
"node": {{"node-a", 0}, {"node-b", 1}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "node", value: "node-a"}: 0,
|
||||
{key: "node", value: "node-b"}: 1,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(0),
|
||||
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -647,9 +649,9 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||
"node": {{"node-a", 0}, {"node-b", 2}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "node", value: "node-a"}: 0,
|
||||
{key: "node", value: "node-b"}: 2,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(0),
|
||||
{key: "node", value: "node-b"}: pointer.Int32Ptr(2),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -672,11 +674,11 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
||||
"zone": {{"zone2", 0}, {"zone1", 1}},
|
||||
"node": {{"node-x", 0}, {"node-a", 1}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 1,
|
||||
{key: "zone", value: "zone2"}: 0,
|
||||
{key: "node", value: "node-a"}: 1,
|
||||
{key: "node", value: "node-x"}: 0,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(1),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(0),
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-x"}: pointer.Int32Ptr(0),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -701,11 +703,11 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
||||
"zone": {{"zone1", 1}, {"zone2", 1}},
|
||||
"node": {{"node-a", 1}, {"node-x", 1}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 1,
|
||||
{key: "zone", value: "zone2"}: 1,
|
||||
{key: "node", value: "node-a"}: 1,
|
||||
{key: "node", value: "node-x"}: 1,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(1),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-x"}: pointer.Int32Ptr(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -733,12 +735,12 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
||||
"zone": {{"zone2", 1}, {"zone1", 3}},
|
||||
"node": {{"node-a", 1}, {"node-x", 1}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 3,
|
||||
{key: "zone", value: "zone2"}: 1,
|
||||
{key: "node", value: "node-a"}: 1,
|
||||
{key: "node", value: "node-b"}: 2,
|
||||
{key: "node", value: "node-x"}: 1,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-b"}: pointer.Int32Ptr(2),
|
||||
{key: "node", value: "node-x"}: pointer.Int32Ptr(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -773,12 +775,12 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
||||
"zone": {{"zone2", 1}, {"zone1", 2}},
|
||||
"node": {{"node-a", 0}, {"node-b", 1}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 2,
|
||||
{key: "zone", value: "zone2"}: 1,
|
||||
{key: "node", value: "node-a"}: 0,
|
||||
{key: "node", value: "node-b"}: 1,
|
||||
{key: "node", value: "node-x"}: 2,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(2),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(0),
|
||||
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-x"}: pointer.Int32Ptr(2),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -813,12 +815,12 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
||||
"zone": {{"zone1", 1}, {"zone2", 1}},
|
||||
"node": {{"node-a", 1}, {"node-b", 1}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 1,
|
||||
{key: "zone", value: "zone2"}: 1,
|
||||
{key: "node", value: "node-a"}: 1,
|
||||
{key: "node", value: "node-b"}: 1,
|
||||
{key: "node", value: "node-x"}: 2,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(1),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-x"}: pointer.Int32Ptr(2),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -894,9 +896,9 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||
"zone": {{"zone1", 1}, {"zone2", 1}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 1,
|
||||
{key: "zone", value: "zone2"}: 1,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(1),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -924,9 +926,9 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||
"zone": {{"zone1", 1}, {"zone2", 2}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 1,
|
||||
{key: "zone", value: "zone2"}: 2,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(1),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(2),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -955,9 +957,9 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||
"zone": {{"zone1", 2}, {"zone2", 2}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 2,
|
||||
{key: "zone", value: "zone2"}: 2,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(2),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(2),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -986,9 +988,9 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||
"zone": {{"zone1", 2}, {"zone2", 2}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 2,
|
||||
{key: "zone", value: "zone2"}: 2,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(2),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(2),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1018,12 +1020,12 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
||||
"zone": {{"zone2", 1}, {"zone1", 3}},
|
||||
"node": {{"node-b", 1}, {"node-x", 1}},
|
||||
},
|
||||
TpPairToMatchNum: map[topologyPair]int32{
|
||||
{key: "zone", value: "zone1"}: 3,
|
||||
{key: "zone", value: "zone2"}: 1,
|
||||
{key: "node", value: "node-a"}: 2,
|
||||
{key: "node", value: "node-b"}: 1,
|
||||
{key: "node", value: "node-x"}: 1,
|
||||
TpPairToMatchNum: map[topologyPair]*int32{
|
||||
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||
{key: "zone", value: "zone2"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-a"}: pointer.Int32Ptr(2),
|
||||
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||
{key: "node", value: "node-x"}: pointer.Int32Ptr(1),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1065,7 +1067,7 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkTestCalPreFilterState(b *testing.B) {
|
||||
func BenchmarkFilter(b *testing.B) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pod *v1.Pod
|
||||
@ -1103,17 +1105,30 @@ func BenchmarkTestCalPreFilterState(b *testing.B) {
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
var state *framework.CycleState
|
||||
b.Run(tt.name, func(b *testing.B) {
|
||||
existingPods, allNodes, _ := st.MakeNodesAndPodsForEvenPodsSpread(tt.pod.Labels, tt.existingPodsNum, tt.allNodesNum, tt.filteredNodesNum)
|
||||
pl := PodTopologySpread{
|
||||
sharedLister: cache.NewSnapshot(existingPods, allNodes),
|
||||
}
|
||||
ctx := context.Background()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
s := pl.PreFilter(context.Background(), framework.NewCycleState(), tt.pod)
|
||||
state = framework.NewCycleState()
|
||||
s := pl.PreFilter(ctx, state, tt.pod)
|
||||
if !s.IsSuccess() {
|
||||
b.Fatal(s.AsError())
|
||||
}
|
||||
filterNode := func(i int) {
|
||||
n, _ := pl.sharedLister.NodeInfos().Get(allNodes[i].Name)
|
||||
pl.Filter(ctx, state, tt.pod, n)
|
||||
}
|
||||
parallelize.Until(ctx, len(allNodes), filterNode)
|
||||
}
|
||||
})
|
||||
b.Run(tt.name+"/Clone", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
state.Clone()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user