mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +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"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync/atomic"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/klog"
|
"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"
|
framework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/internal/parallelize"
|
"k8s.io/kubernetes/pkg/scheduler/internal/parallelize"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
"k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
||||||
@ -48,7 +48,7 @@ type preFilterState struct {
|
|||||||
// it's not guaranteed to be the 2nd minimum match number.
|
// it's not guaranteed to be the 2nd minimum match number.
|
||||||
TpKeyToCriticalPaths map[string]*criticalPaths
|
TpKeyToCriticalPaths map[string]*criticalPaths
|
||||||
// TpPairToMatchNum is keyed with topologyPair, and valued with the number of matching pods.
|
// 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.
|
// 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 are shared because they don't change.
|
||||||
Constraints: s.Constraints,
|
Constraints: s.Constraints,
|
||||||
TpKeyToCriticalPaths: make(map[string]*criticalPaths, len(s.TpKeyToCriticalPaths)),
|
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 {
|
for tpKey, paths := range s.TpKeyToCriticalPaths {
|
||||||
copy.TpKeyToCriticalPaths[tpKey] = &criticalPaths{paths[0], paths[1]}
|
copy.TpKeyToCriticalPaths[tpKey] = &criticalPaths{paths[0], paths[1]}
|
||||||
}
|
}
|
||||||
for tpPair, matchNum := range s.TpPairToMatchNum {
|
for tpPair, matchNum := range s.TpPairToMatchNum {
|
||||||
copyPair := topologyPair{key: tpPair.key, value: tpPair.value}
|
copyPair := topologyPair{key: tpPair.key, value: tpPair.value}
|
||||||
copy.TpPairToMatchNum[copyPair] = matchNum
|
copyCount := *matchNum
|
||||||
|
copy.TpPairToMatchNum[copyPair] = ©Count
|
||||||
}
|
}
|
||||||
return ©
|
return ©
|
||||||
}
|
}
|
||||||
@ -137,9 +138,9 @@ func (s *preFilterState) updateWithPod(updatedPod, preemptorPod *v1.Pod, node *v
|
|||||||
|
|
||||||
k, v := constraint.TopologyKey, node.Labels[constraint.TopologyKey]
|
k, v := constraint.TopologyKey, node.Labels[constraint.TopologyKey]
|
||||||
pair := topologyPair{key: k, value: v}
|
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
|
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{
|
s := preFilterState{
|
||||||
Constraints: constraints,
|
Constraints: constraints,
|
||||||
TpKeyToCriticalPaths: make(map[string]*criticalPaths, len(constraints)),
|
TpKeyToCriticalPaths: make(map[string]*criticalPaths, len(constraints)),
|
||||||
TpPairToMatchNum: make(map[topologyPair]int32),
|
TpPairToMatchNum: make(map[topologyPair]*int32, sizeHeuristic(len(allNodes), constraints)),
|
||||||
}
|
}
|
||||||
addTopologyPairMatchNum := func(pair topologyPair, num int32) {
|
for _, n := range allNodes {
|
||||||
lock.Lock()
|
node := n.Node()
|
||||||
s.TpPairToMatchNum[pair] += num
|
if node == nil {
|
||||||
lock.Unlock()
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processNode := func(i int) {
|
processNode := func(i int) {
|
||||||
nodeInfo := allNodes[i]
|
nodeInfo := allNodes[i]
|
||||||
node := nodeInfo.Node()
|
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 {
|
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 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if constraint.Selector.Matches(labels.Set(existingPod.Labels)) {
|
|
||||||
matchTotal++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pair := topologyPair{key: constraint.TopologyKey, value: node.Labels[constraint.TopologyKey]}
|
pair := topologyPair{key: constraint.TopologyKey, value: node.Labels[constraint.TopologyKey]}
|
||||||
addTopologyPairMatchNum(pair, matchTotal)
|
tpCount := s.TpPairToMatchNum[pair]
|
||||||
|
if tpCount == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
count := countPodsMatchSelector(nodeInfo.Pods(), constraint.Selector, pod.Namespace)
|
||||||
|
atomic.AddInt32(tpCount, int32(count))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parallelize.Until(context.Background(), len(allNodes), processNode)
|
parallelize.Until(context.Background(), len(allNodes), processNode)
|
||||||
@ -275,7 +268,7 @@ func (pl *PodTopologySpread) calPreFilterState(pod *v1.Pod) (*preFilterState, er
|
|||||||
s.TpKeyToCriticalPaths[key] = newCriticalPaths()
|
s.TpKeyToCriticalPaths[key] = newCriticalPaths()
|
||||||
}
|
}
|
||||||
for pair, num := range s.TpPairToMatchNum {
|
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
|
return &s, nil
|
||||||
@ -322,7 +315,10 @@ func (pl *PodTopologySpread) Filter(ctx context.Context, cycleState *framework.C
|
|||||||
// judging criteria:
|
// judging criteria:
|
||||||
// 'existing matching num' + 'if self-match (1 or 0)' - 'global min matching num' <= 'maxSkew'
|
// 'existing matching num' + 'if self-match (1 or 0)' - 'global min matching num' <= 'maxSkew'
|
||||||
minMatchNum := paths[0].MatchNum
|
minMatchNum := paths[0].MatchNum
|
||||||
matchNum := s.TpPairToMatchNum[pair]
|
matchNum := int32(0)
|
||||||
|
if tpCount := s.TpPairToMatchNum[pair]; tpCount != nil {
|
||||||
|
matchNum = *tpCount
|
||||||
|
}
|
||||||
skew := matchNum + selfMatchNum - minMatchNum
|
skew := matchNum + selfMatchNum - minMatchNum
|
||||||
if skew > c.MaxSkew {
|
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)
|
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
|
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"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
framework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
|
framework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/internal/cache"
|
"k8s.io/kubernetes/pkg/scheduler/internal/cache"
|
||||||
|
"k8s.io/kubernetes/pkg/scheduler/internal/parallelize"
|
||||||
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
||||||
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
|
"k8s.io/utils/pointer"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cmpOpts = []cmp.Option{
|
var cmpOpts = []cmp.Option{
|
||||||
@ -86,9 +88,9 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
"zone": {{"zone1", 0}, {"zone2", 0}},
|
"zone": {{"zone1", 0}, {"zone2", 0}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 0,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(0),
|
||||||
{key: "zone", value: "zone2"}: 0,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(0),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -121,9 +123,9 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
"zone": {{"zone2", 2}, {"zone1", 3}},
|
"zone": {{"zone2", 2}, {"zone1", 3}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 3,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||||
{key: "zone", value: "zone2"}: 2,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(2),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -158,10 +160,10 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
"zone": {{"zone3", 0}, {"zone2", 2}},
|
"zone": {{"zone3", 0}, {"zone2", 2}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 3,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||||
{key: "zone", value: "zone2"}: 2,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(2),
|
||||||
{key: "zone", value: "zone3"}: 0,
|
{key: "zone", value: "zone3"}: pointer.Int32Ptr(0),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -194,9 +196,9 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
"zone": {{"zone2", 1}, {"zone1", 2}},
|
"zone": {{"zone2", 1}, {"zone1", 2}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 2,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(2),
|
||||||
{key: "zone", value: "zone2"}: 1,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(1),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -238,13 +240,13 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
"zone": {{"zone1", 3}, {"zone2", 4}},
|
"zone": {{"zone1", 3}, {"zone2", 4}},
|
||||||
"node": {{"node-x", 0}, {"node-b", 1}},
|
"node": {{"node-x", 0}, {"node-b", 1}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 3,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||||
{key: "zone", value: "zone2"}: 4,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(4),
|
||||||
{key: "node", value: "node-a"}: 2,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(2),
|
||||||
{key: "node", value: "node-b"}: 1,
|
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-x"}: 0,
|
{key: "node", value: "node-x"}: pointer.Int32Ptr(0),
|
||||||
{key: "node", value: "node-y"}: 4,
|
{key: "node", value: "node-y"}: pointer.Int32Ptr(4),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -287,12 +289,12 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
"zone": {{"zone1", 3}, {"zone2", 4}},
|
"zone": {{"zone1", 3}, {"zone2", 4}},
|
||||||
"node": {{"node-b", 1}, {"node-a", 2}},
|
"node": {{"node-b", 1}, {"node-a", 2}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 3,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||||
{key: "zone", value: "zone2"}: 4,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(4),
|
||||||
{key: "node", value: "node-a"}: 2,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(2),
|
||||||
{key: "node", value: "node-b"}: 1,
|
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-y"}: 4,
|
{key: "node", value: "node-y"}: pointer.Int32Ptr(4),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -328,12 +330,12 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
"zone": {{"zone2", 0}, {"zone1", 1}},
|
"zone": {{"zone2", 0}, {"zone1", 1}},
|
||||||
"node": {{"node-a", 0}, {"node-y", 0}},
|
"node": {{"node-a", 0}, {"node-y", 0}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 1,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(1),
|
||||||
{key: "zone", value: "zone2"}: 0,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(0),
|
||||||
{key: "node", value: "node-a"}: 0,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(0),
|
||||||
{key: "node", value: "node-b"}: 1,
|
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-y"}: 0,
|
{key: "node", value: "node-y"}: pointer.Int32Ptr(0),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -374,12 +376,12 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
"zone": {{"zone1", 3}, {"zone2", 4}},
|
"zone": {{"zone1", 3}, {"zone2", 4}},
|
||||||
"node": {{"node-b", 0}, {"node-a", 1}},
|
"node": {{"node-b", 0}, {"node-a", 1}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 3,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||||
{key: "zone", value: "zone2"}: 4,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(4),
|
||||||
{key: "node", value: "node-a"}: 1,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-b"}: 0,
|
{key: "node", value: "node-b"}: pointer.Int32Ptr(0),
|
||||||
{key: "node", value: "node-y"}: 2,
|
{key: "node", value: "node-y"}: pointer.Int32Ptr(2),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -422,12 +424,12 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
"zone": {{"zone1", 3}, {"zone2", 4}},
|
"zone": {{"zone1", 3}, {"zone2", 4}},
|
||||||
"node": {{"node-b", 1}, {"node-a", 2}},
|
"node": {{"node-b", 1}, {"node-a", 2}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 3,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||||
{key: "zone", value: "zone2"}: 4,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(4),
|
||||||
{key: "node", value: "node-a"}: 2,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(2),
|
||||||
{key: "node", value: "node-b"}: 1,
|
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-y"}: 4,
|
{key: "node", value: "node-y"}: pointer.Int32Ptr(4),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -459,7 +461,7 @@ func TestPreFilterState(t *testing.T) {
|
|||||||
"node": newCriticalPaths(),
|
"node": newCriticalPaths(),
|
||||||
"rack": 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{
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
"zone": newCriticalPaths(),
|
"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{
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
"node": {{"node-b", 0}, {"node-a", 1}},
|
"node": {{"node-b", 0}, {"node-a", 1}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "node", value: "node-a"}: 1,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-b"}: 0,
|
{key: "node", value: "node-b"}: pointer.Int32Ptr(0),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -597,9 +599,9 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
"node": {{"node-a", 1}, {"node-b", 1}},
|
"node": {{"node-a", 1}, {"node-b", 1}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "node", value: "node-a"}: 1,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-b"}: 1,
|
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -622,9 +624,9 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
"node": {{"node-a", 0}, {"node-b", 1}},
|
"node": {{"node-a", 0}, {"node-b", 1}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "node", value: "node-a"}: 0,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(0),
|
||||||
{key: "node", value: "node-b"}: 1,
|
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -647,9 +649,9 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
"node": {{"node-a", 0}, {"node-b", 2}},
|
"node": {{"node-a", 0}, {"node-b", 2}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "node", value: "node-a"}: 0,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(0),
|
||||||
{key: "node", value: "node-b"}: 2,
|
{key: "node", value: "node-b"}: pointer.Int32Ptr(2),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -672,11 +674,11 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
"zone": {{"zone2", 0}, {"zone1", 1}},
|
"zone": {{"zone2", 0}, {"zone1", 1}},
|
||||||
"node": {{"node-x", 0}, {"node-a", 1}},
|
"node": {{"node-x", 0}, {"node-a", 1}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 1,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(1),
|
||||||
{key: "zone", value: "zone2"}: 0,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(0),
|
||||||
{key: "node", value: "node-a"}: 1,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-x"}: 0,
|
{key: "node", value: "node-x"}: pointer.Int32Ptr(0),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -701,11 +703,11 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
"zone": {{"zone1", 1}, {"zone2", 1}},
|
"zone": {{"zone1", 1}, {"zone2", 1}},
|
||||||
"node": {{"node-a", 1}, {"node-x", 1}},
|
"node": {{"node-a", 1}, {"node-x", 1}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 1,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(1),
|
||||||
{key: "zone", value: "zone2"}: 1,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-a"}: 1,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-x"}: 1,
|
{key: "node", value: "node-x"}: pointer.Int32Ptr(1),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -733,12 +735,12 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
"zone": {{"zone2", 1}, {"zone1", 3}},
|
"zone": {{"zone2", 1}, {"zone1", 3}},
|
||||||
"node": {{"node-a", 1}, {"node-x", 1}},
|
"node": {{"node-a", 1}, {"node-x", 1}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 3,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||||
{key: "zone", value: "zone2"}: 1,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-a"}: 1,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-b"}: 2,
|
{key: "node", value: "node-b"}: pointer.Int32Ptr(2),
|
||||||
{key: "node", value: "node-x"}: 1,
|
{key: "node", value: "node-x"}: pointer.Int32Ptr(1),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -773,12 +775,12 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
"zone": {{"zone2", 1}, {"zone1", 2}},
|
"zone": {{"zone2", 1}, {"zone1", 2}},
|
||||||
"node": {{"node-a", 0}, {"node-b", 1}},
|
"node": {{"node-a", 0}, {"node-b", 1}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 2,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(2),
|
||||||
{key: "zone", value: "zone2"}: 1,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-a"}: 0,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(0),
|
||||||
{key: "node", value: "node-b"}: 1,
|
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-x"}: 2,
|
{key: "node", value: "node-x"}: pointer.Int32Ptr(2),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -813,12 +815,12 @@ func TestPreFilterStateAddPod(t *testing.T) {
|
|||||||
"zone": {{"zone1", 1}, {"zone2", 1}},
|
"zone": {{"zone1", 1}, {"zone2", 1}},
|
||||||
"node": {{"node-a", 1}, {"node-b", 1}},
|
"node": {{"node-a", 1}, {"node-b", 1}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 1,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(1),
|
||||||
{key: "zone", value: "zone2"}: 1,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-a"}: 1,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-b"}: 1,
|
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-x"}: 2,
|
{key: "node", value: "node-x"}: pointer.Int32Ptr(2),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -894,9 +896,9 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
|||||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
"zone": {{"zone1", 1}, {"zone2", 1}},
|
"zone": {{"zone1", 1}, {"zone2", 1}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 1,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(1),
|
||||||
{key: "zone", value: "zone2"}: 1,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(1),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -924,9 +926,9 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
|||||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
"zone": {{"zone1", 1}, {"zone2", 2}},
|
"zone": {{"zone1", 1}, {"zone2", 2}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 1,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(1),
|
||||||
{key: "zone", value: "zone2"}: 2,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(2),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -955,9 +957,9 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
|||||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
"zone": {{"zone1", 2}, {"zone2", 2}},
|
"zone": {{"zone1", 2}, {"zone2", 2}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 2,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(2),
|
||||||
{key: "zone", value: "zone2"}: 2,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(2),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -986,9 +988,9 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
|||||||
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
TpKeyToCriticalPaths: map[string]*criticalPaths{
|
||||||
"zone": {{"zone1", 2}, {"zone2", 2}},
|
"zone": {{"zone1", 2}, {"zone2", 2}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 2,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(2),
|
||||||
{key: "zone", value: "zone2"}: 2,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(2),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1018,12 +1020,12 @@ func TestPreFilterStateRemovePod(t *testing.T) {
|
|||||||
"zone": {{"zone2", 1}, {"zone1", 3}},
|
"zone": {{"zone2", 1}, {"zone1", 3}},
|
||||||
"node": {{"node-b", 1}, {"node-x", 1}},
|
"node": {{"node-b", 1}, {"node-x", 1}},
|
||||||
},
|
},
|
||||||
TpPairToMatchNum: map[topologyPair]int32{
|
TpPairToMatchNum: map[topologyPair]*int32{
|
||||||
{key: "zone", value: "zone1"}: 3,
|
{key: "zone", value: "zone1"}: pointer.Int32Ptr(3),
|
||||||
{key: "zone", value: "zone2"}: 1,
|
{key: "zone", value: "zone2"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-a"}: 2,
|
{key: "node", value: "node-a"}: pointer.Int32Ptr(2),
|
||||||
{key: "node", value: "node-b"}: 1,
|
{key: "node", value: "node-b"}: pointer.Int32Ptr(1),
|
||||||
{key: "node", value: "node-x"}: 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 {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
pod *v1.Pod
|
pod *v1.Pod
|
||||||
@ -1103,17 +1105,30 @@ func BenchmarkTestCalPreFilterState(b *testing.B) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
var state *framework.CycleState
|
||||||
b.Run(tt.name, func(b *testing.B) {
|
b.Run(tt.name, func(b *testing.B) {
|
||||||
existingPods, allNodes, _ := st.MakeNodesAndPodsForEvenPodsSpread(tt.pod.Labels, tt.existingPodsNum, tt.allNodesNum, tt.filteredNodesNum)
|
existingPods, allNodes, _ := st.MakeNodesAndPodsForEvenPodsSpread(tt.pod.Labels, tt.existingPodsNum, tt.allNodesNum, tt.filteredNodesNum)
|
||||||
pl := PodTopologySpread{
|
pl := PodTopologySpread{
|
||||||
sharedLister: cache.NewSnapshot(existingPods, allNodes),
|
sharedLister: cache.NewSnapshot(existingPods, allNodes),
|
||||||
}
|
}
|
||||||
|
ctx := context.Background()
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
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() {
|
if !s.IsSuccess() {
|
||||||
b.Fatal(s.AsError())
|
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