Skip to content

Commit 1a325db

Browse files
authored
Merge pull request kubernetes#76973 from Huang-Wei/lazy-init-int64-ptr
scheduler: fix perf downgrade of cases without presence of (anti-)affinity pods
2 parents 7a5bc7c + 492b970 commit 1a325db

File tree

1 file changed

+30
-25
lines changed

1 file changed

+30
-25
lines changed

pkg/scheduler/algorithm/priorities/interpod_affinity.go

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package priorities
1919
import (
2020
"context"
2121
"sync"
22+
"sync/atomic"
2223

2324
"k8s.io/api/core/v1"
2425
apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -63,15 +64,15 @@ type podAffinityPriorityMap struct {
6364
nodes []*v1.Node
6465
// counts store the mapping from node name to so-far computed score of
6566
// the node.
66-
counts map[string]float64
67+
counts map[string]*int64
6768
// The first error that we faced.
6869
firstError error
6970
}
7071

7172
func newPodAffinityPriorityMap(nodes []*v1.Node) *podAffinityPriorityMap {
7273
return &podAffinityPriorityMap{
7374
nodes: nodes,
74-
counts: make(map[string]float64, len(nodes)),
75+
counts: make(map[string]*int64, len(nodes)),
7576
}
7677
}
7778

@@ -83,7 +84,7 @@ func (p *podAffinityPriorityMap) setError(err error) {
8384
}
8485
}
8586

86-
func (p *podAffinityPriorityMap) processTerm(term *v1.PodAffinityTerm, podDefiningAffinityTerm, podToCheck *v1.Pod, fixedNode *v1.Node, weight float64) {
87+
func (p *podAffinityPriorityMap) processTerm(term *v1.PodAffinityTerm, podDefiningAffinityTerm, podToCheck *v1.Pod, fixedNode *v1.Node, weight int64) {
8788
namespaces := priorityutil.GetNamespacesFromPodAffinityTerm(podDefiningAffinityTerm, term)
8889
selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector)
8990
if err != nil {
@@ -92,22 +93,18 @@ func (p *podAffinityPriorityMap) processTerm(term *v1.PodAffinityTerm, podDefini
9293
}
9394
match := priorityutil.PodMatchesTermsNamespaceAndSelector(podToCheck, namespaces, selector)
9495
if match {
95-
func() {
96-
p.Lock()
97-
defer p.Unlock()
98-
for _, node := range p.nodes {
99-
if priorityutil.NodesHaveSameTopologyKey(node, fixedNode, term.TopologyKey) {
100-
p.counts[node.Name] += weight
101-
}
96+
for _, node := range p.nodes {
97+
if priorityutil.NodesHaveSameTopologyKey(node, fixedNode, term.TopologyKey) {
98+
atomic.AddInt64(p.counts[node.Name], weight)
10299
}
103-
}()
100+
}
104101
}
105102
}
106103

107104
func (p *podAffinityPriorityMap) processTerms(terms []v1.WeightedPodAffinityTerm, podDefiningAffinityTerm, podToCheck *v1.Pod, fixedNode *v1.Node, multiplier int) {
108105
for i := range terms {
109106
term := &terms[i]
110-
p.processTerm(&term.PodAffinityTerm, podDefiningAffinityTerm, podToCheck, fixedNode, float64(term.Weight*int32(multiplier)))
107+
p.processTerm(&term.PodAffinityTerm, podDefiningAffinityTerm, podToCheck, fixedNode, int64(term.Weight*int32(multiplier)))
111108
}
112109
}
113110

@@ -121,17 +118,21 @@ func (ipa *InterPodAffinity) CalculateInterPodAffinityPriority(pod *v1.Pod, node
121118
hasAffinityConstraints := affinity != nil && affinity.PodAffinity != nil
122119
hasAntiAffinityConstraints := affinity != nil && affinity.PodAntiAffinity != nil
123120

121+
// priorityMap stores the mapping from node name to so-far computed score of
122+
// the node.
123+
pm := newPodAffinityPriorityMap(nodes)
124124
allNodeNames := make([]string, 0, len(nodeNameToInfo))
125+
lazyInit := hasAffinityConstraints || hasAntiAffinityConstraints
125126
for name := range nodeNameToInfo {
126127
allNodeNames = append(allNodeNames, name)
128+
// if pod has affinity defined, or target node has affinityPods
129+
if lazyInit || len(nodeNameToInfo[name].PodsWithAffinity()) != 0 {
130+
pm.counts[name] = new(int64)
131+
}
127132
}
128133

129134
// convert the topology key based weights to the node name based weights
130-
var maxCount float64
131-
var minCount float64
132-
// priorityMap stores the mapping from node name to so-far computed score of
133-
// the node.
134-
pm := newPodAffinityPriorityMap(nodes)
135+
var maxCount, minCount int64
135136

136137
processPod := func(existingPod *v1.Pod) error {
137138
existingPodNode, err := ipa.info.GetNodeInfo(existingPod.Spec.NodeName)
@@ -172,7 +173,7 @@ func (ipa *InterPodAffinity) CalculateInterPodAffinityPriority(pod *v1.Pod, node
172173
// terms = append(terms, existingPodAffinity.PodAffinity.RequiredDuringSchedulingRequiredDuringExecution...)
173174
//}
174175
for _, term := range terms {
175-
pm.processTerm(&term, existingPod, pod, existingPodNode, float64(ipa.hardPodAffinityWeight))
176+
pm.processTerm(&term, existingPod, pod, existingPodNode, int64(ipa.hardPodAffinityWeight))
176177
}
177178
}
178179
// For every soft pod affinity term of <existingPod>, if <pod> matches the term,
@@ -194,7 +195,7 @@ func (ipa *InterPodAffinity) CalculateInterPodAffinityPriority(pod *v1.Pod, node
194195
nodeInfo := nodeNameToInfo[allNodeNames[i]]
195196
if nodeInfo.Node() != nil {
196197
if hasAffinityConstraints || hasAntiAffinityConstraints {
197-
// We need to process all the nodes.
198+
// We need to process all the pods.
198199
for _, existingPod := range nodeInfo.Pods() {
199200
if err := processPod(existingPod); err != nil {
200201
pm.setError(err)
@@ -217,20 +218,24 @@ func (ipa *InterPodAffinity) CalculateInterPodAffinityPriority(pod *v1.Pod, node
217218
}
218219

219220
for _, node := range nodes {
220-
if pm.counts[node.Name] > maxCount {
221-
maxCount = pm.counts[node.Name]
221+
if pm.counts[node.Name] == nil {
222+
continue
223+
}
224+
if *pm.counts[node.Name] > maxCount {
225+
maxCount = *pm.counts[node.Name]
222226
}
223-
if pm.counts[node.Name] < minCount {
224-
minCount = pm.counts[node.Name]
227+
if *pm.counts[node.Name] < minCount {
228+
minCount = *pm.counts[node.Name]
225229
}
226230
}
227231

228232
// calculate final priority score for each node
229233
result := make(schedulerapi.HostPriorityList, 0, len(nodes))
234+
maxMinDiff := maxCount - minCount
230235
for _, node := range nodes {
231236
fScore := float64(0)
232-
if (maxCount - minCount) > 0 {
233-
fScore = float64(schedulerapi.MaxPriority) * ((pm.counts[node.Name] - minCount) / (maxCount - minCount))
237+
if maxMinDiff > 0 && pm.counts[node.Name] != nil {
238+
fScore = float64(schedulerapi.MaxPriority) * (float64(*pm.counts[node.Name]-minCount) / float64(maxCount-minCount))
234239
}
235240
result = append(result, schedulerapi.HostPriority{Host: node.Name, Score: int(fScore)})
236241
if klog.V(10) {

0 commit comments

Comments
 (0)