Skip to content

Commit 82e34ae

Browse files
committed
feat: introduce memset binder
Signed-off-by: linzhecheng <linzhecheng@bytedance.com>
1 parent 8851169 commit 82e34ae

File tree

4 files changed

+168
-18
lines changed

4 files changed

+168
-18
lines changed

pkg/agent/sysadvisor/plugin/qosaware/resource/memory/advisor.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func init() {
4545
headroompolicy.RegisterInitializer(types.MemoryHeadroomPolicyCanonical, headroompolicy.NewPolicyCanonical)
4646
memadvisorplugin.RegisterInitializer(memadvisorplugin.CacheReaper, memadvisorplugin.NewCacheReaper)
4747
memadvisorplugin.RegisterInitializer(memadvisorplugin.MemoryGuard, memadvisorplugin.NewMemoryGuard)
48+
memadvisorplugin.RegisterInitializer(memadvisorplugin.MemsetBinder, memadvisorplugin.NewMemsetBinder)
4849
}
4950

5051
const (
@@ -230,6 +231,10 @@ func (ra *memoryResourceAdvisor) detectNUMAPressure(numaID int) (*types.MemoryPr
230231
return nil, err
231232
}
232233

234+
general.Infof("numa %v metrics, free: %+v, total: %+v, scaleFactor: %+v", numaID,
235+
resource.NewQuantity(int64(free), resource.BinarySI).String(),
236+
resource.NewQuantity(int64(total), resource.BinarySI).String(), scaleFactor)
237+
233238
targetReclaimed := resource.NewQuantity(0, resource.BinarySI)
234239

235240
pressureState := types.MemoryPressureNoRisk
@@ -253,7 +258,9 @@ func (ra *memoryResourceAdvisor) detectNodePressureCondition() (*types.MemoryPre
253258
return nil, err
254259
}
255260

256-
general.Infof("system watermark metrics, free: %+v, total: %+v, scaleFactor: %+v", free, total, scaleFactor)
261+
general.Infof("system watermark metrics, free: %+v, total: %+v, scaleFactor: %+v",
262+
resource.NewQuantity(int64(free), resource.BinarySI).String(),
263+
resource.NewQuantity(int64(total), resource.BinarySI).String(), scaleFactor)
257264

258265
targetReclaimed := resource.NewQuantity(0, resource.BinarySI)
259266

pkg/agent/sysadvisor/plugin/qosaware/resource/memory/advisor_test.go

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -234,21 +234,6 @@ var defaultNumaMetrics = []numaMetric{
234234
},
235235
}
236236

237-
var tuneMemcgNodeMetrics = []nodeMetric{
238-
{
239-
metricName: coreconsts.MetricMemFreeSystem,
240-
metricValue: metricutil.MetricData{Value: 80 << 30},
241-
},
242-
{
243-
metricName: coreconsts.MetricMemTotalSystem,
244-
metricValue: metricutil.MetricData{Value: 500 << 30},
245-
},
246-
{
247-
metricName: coreconsts.MetricMemScaleFactorSystem,
248-
metricValue: metricutil.MetricData{Value: 500},
249-
},
250-
}
251-
252237
var dropCacheNodeMetrics = []nodeMetric{
253238
{
254239
metricName: coreconsts.MetricMemFreeSystem,
@@ -634,6 +619,63 @@ func TestUpdate(t *testing.T) {
634619
},
635620
},
636621
},
622+
{
623+
name: "bind memset",
624+
pools: map[string]*types.PoolInfo{
625+
state.PoolNameReserve: {
626+
PoolName: state.PoolNameReserve,
627+
TopologyAwareAssignments: map[int]machine.CPUSet{
628+
0: machine.MustParse("0"),
629+
1: machine.MustParse("24"),
630+
},
631+
OriginalTopologyAwareAssignments: map[int]machine.CPUSet{
632+
0: machine.MustParse("0"),
633+
1: machine.MustParse("24"),
634+
},
635+
},
636+
},
637+
reclaimedEnable: false,
638+
needRecvAdvices: true,
639+
containers: []*types.ContainerInfo{
640+
makeContainerInfo("uid1", "default", "pod1", "c1", consts.PodAnnotationQoSLevelReclaimedCores, nil,
641+
map[int]machine.CPUSet{
642+
0: machine.MustParse("1"),
643+
1: machine.MustParse("25"),
644+
}, 200<<30),
645+
makeContainerInfo("uid2", "default", "pod2", "c2", consts.PodAnnotationQoSLevelReclaimedCores, nil,
646+
map[int]machine.CPUSet{
647+
0: machine.MustParse("1"),
648+
1: machine.MustParse("25"),
649+
}, 200<<30),
650+
makeContainerInfo("uid3", "default", "pod3", "c3", consts.PodAnnotationQoSLevelReclaimedCores, nil,
651+
map[int]machine.CPUSet{
652+
0: machine.MustParse("1"),
653+
}, 200<<30),
654+
},
655+
plugins: []types.MemoryAdvisorPluginName{memadvisorplugin.MemsetBinder},
656+
nodeMetrics: defaultNodeMetrics,
657+
numaMetrics: defaultNumaMetrics,
658+
wantHeadroom: *resource.NewQuantity(996<<30, resource.DecimalSI),
659+
wantAdviceResult: types.InternalMemoryCalculationResult{
660+
ContainerEntries: []types.ContainerMemoryAdvices{
661+
{
662+
PodUID: "uid1",
663+
ContainerName: "c1",
664+
Values: map[string]string{string(memoryadvisor.ControKnobKeyCPUSetMems): "0-1"},
665+
},
666+
{
667+
PodUID: "uid2",
668+
ContainerName: "c2",
669+
Values: map[string]string{string(memoryadvisor.ControKnobKeyCPUSetMems): "0-1"},
670+
},
671+
{
672+
PodUID: "uid3",
673+
ContainerName: "c3",
674+
Values: map[string]string{string(memoryadvisor.ControKnobKeyCPUSetMems): "0"},
675+
},
676+
},
677+
},
678+
},
637679
}
638680

639681
for _, tt := range tests {
@@ -687,8 +729,8 @@ func TestUpdate(t *testing.T) {
687729
if tt.needRecvAdvices {
688730
result := <-recvCh
689731

690-
assert.Equal(t, tt.wantAdviceResult.ExtraEntries, result.ExtraEntries)
691-
assert.Equal(t, tt.wantAdviceResult.ContainerEntries, result.ContainerEntries)
732+
assert.ElementsMatch(t, tt.wantAdviceResult.ExtraEntries, result.ExtraEntries)
733+
assert.ElementsMatch(t, tt.wantAdviceResult.ContainerEntries, result.ContainerEntries)
692734
}
693735
headroom, err := advisor.GetHeadroom()
694736

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
Copyright 2022 The Katalyst Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package plugin
18+
19+
import (
20+
"sync"
21+
22+
apiconsts "github.com/kubewharf/katalyst-api/pkg/consts"
23+
"github.com/kubewharf/katalyst-core/pkg/agent/qrm-plugins/memory/dynamicpolicy/memoryadvisor"
24+
"github.com/kubewharf/katalyst-core/pkg/agent/sysadvisor/metacache"
25+
"github.com/kubewharf/katalyst-core/pkg/agent/sysadvisor/types"
26+
"github.com/kubewharf/katalyst-core/pkg/config"
27+
"github.com/kubewharf/katalyst-core/pkg/consts"
28+
"github.com/kubewharf/katalyst-core/pkg/metaserver"
29+
"github.com/kubewharf/katalyst-core/pkg/metrics"
30+
"github.com/kubewharf/katalyst-core/pkg/util/general"
31+
"github.com/kubewharf/katalyst-core/pkg/util/machine"
32+
"github.com/kubewharf/katalyst-core/pkg/util/native"
33+
)
34+
35+
const (
36+
MemsetBinder = "memset-binder"
37+
)
38+
39+
type memsetBinder struct {
40+
mutex sync.RWMutex
41+
metaReader metacache.MetaReader
42+
emitter metrics.MetricEmitter
43+
containerMemset map[consts.PodContainerName]machine.CPUSet
44+
}
45+
46+
func NewMemsetBinder(conf *config.Configuration, extraConfig interface{}, metaReader metacache.MetaReader, metaServer *metaserver.MetaServer, emitter metrics.MetricEmitter) MemoryAdvisorPlugin {
47+
return &memsetBinder{
48+
metaReader: metaReader,
49+
emitter: emitter,
50+
}
51+
}
52+
53+
func (mb *memsetBinder) reclaimedContainersFilter(ci *types.ContainerInfo) bool {
54+
return ci != nil && ci.QoSLevel == apiconsts.PodAnnotationQoSLevelReclaimedCores
55+
}
56+
57+
func (mb *memsetBinder) Reconcile(status *types.MemoryPressureStatus) error {
58+
containerMemset := make(map[consts.PodContainerName]machine.CPUSet)
59+
containers := mb.metaReader.GetContainers(mb.reclaimedContainersFilter)
60+
for _, ci := range containers {
61+
memset := machine.CPUSet2MemSet(ci.TopologyAwareAssignments)
62+
containerMemset[native.GeneratePodContainerName(ci.PodUID, ci.ContainerName)] = memset
63+
}
64+
mb.mutex.Lock()
65+
defer mb.mutex.Unlock()
66+
mb.containerMemset = containerMemset
67+
68+
return nil
69+
}
70+
71+
func (mb *memsetBinder) GetAdvices() types.InternalMemoryCalculationResult {
72+
mb.mutex.RLock()
73+
defer mb.mutex.RUnlock()
74+
result := types.InternalMemoryCalculationResult{}
75+
for podContainerName, memset := range mb.containerMemset {
76+
podUID, containerName, err := native.ParsePodContainerName(podContainerName)
77+
if err != nil {
78+
general.Errorf("parse podContainerName %v err %v", podContainerName, err)
79+
continue
80+
}
81+
entry := types.ContainerMemoryAdvices{
82+
PodUID: podUID,
83+
ContainerName: containerName,
84+
Values: map[string]string{string(memoryadvisor.ControKnobKeyCPUSetMems): memset.String()},
85+
}
86+
result.ContainerEntries = append(result.ContainerEntries, entry)
87+
}
88+
89+
return result
90+
}

pkg/util/machine/util.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,14 @@ func GetSiblingNUMAs(numaID int, topology *CPUTopology) (CPUSet, error) {
110110

111111
return numaSet, nil
112112
}
113+
114+
// CPUSet2MemSet returns memset for cpuset
115+
func CPUSet2MemSet(assignment map[int]CPUSet) CPUSet {
116+
memset := NewCPUSet()
117+
for numaID, cpuset := range assignment {
118+
if cpuset.Size() > 0 {
119+
memset.Add(numaID)
120+
}
121+
}
122+
return memset
123+
}

0 commit comments

Comments
 (0)