247 lines
7.7 KiB
Diff
247 lines
7.7 KiB
Diff
From f7d9bc26368763d9c0bc9e7fc462dc0ab99a1784 Mon Sep 17 00:00:00 2001
|
|
From: hanchao <hanchao63@huawei.com>
|
|
Date: Fri, 16 Jun 2023 13:10:42 +0800
|
|
Subject: [PATCH 06/13] rubik: fix that value of memory.high_async_ratio lost
|
|
efficacy
|
|
|
|
---
|
|
pkg/services/dynmemory/dynmemory.go | 22 +++++++-
|
|
pkg/services/dynmemory/fssr.go | 78 +++++++++++++++++------------
|
|
2 files changed, 67 insertions(+), 33 deletions(-)
|
|
|
|
diff --git a/pkg/services/dynmemory/dynmemory.go b/pkg/services/dynmemory/dynmemory.go
|
|
index da859dd..b73f476 100644
|
|
--- a/pkg/services/dynmemory/dynmemory.go
|
|
+++ b/pkg/services/dynmemory/dynmemory.go
|
|
@@ -6,6 +6,7 @@ import (
|
|
"time"
|
|
|
|
"isula.org/rubik/pkg/api"
|
|
+ "isula.org/rubik/pkg/core/typedef"
|
|
"isula.org/rubik/pkg/services/helper"
|
|
"k8s.io/apimachinery/pkg/util/wait"
|
|
)
|
|
@@ -15,6 +16,7 @@ type DynMemoryAdapter interface {
|
|
preStart(api.Viewer) error
|
|
getInterval() int
|
|
dynamicAdjust()
|
|
+ setOfflinePod(path string) error
|
|
}
|
|
type dynMemoryConfig struct {
|
|
Policy string `json:"policy,omitempty"`
|
|
@@ -42,11 +44,11 @@ type DynMemory struct {
|
|
}
|
|
|
|
// PreStart is an interface for calling a collection of methods when the service is pre-started
|
|
-func (dynMem *DynMemory) PreStart(api api.Viewer) error {
|
|
+func (dynMem *DynMemory) PreStart(viewer api.Viewer) error {
|
|
if dynMem.dynMemoryAdapter == nil {
|
|
return nil
|
|
}
|
|
- return dynMem.dynMemoryAdapter.preStart(api)
|
|
+ return dynMem.dynMemoryAdapter.preStart(viewer)
|
|
}
|
|
|
|
// SetConfig is an interface that invoke the ConfigHandler to obtain the corresponding configuration.
|
|
@@ -81,6 +83,22 @@ func (dynMem *DynMemory) IsRunner() bool {
|
|
return true
|
|
}
|
|
|
|
+// AddPod to deal the event of adding a pod.
|
|
+func (dynMem *DynMemory) AddPod(podInfo *typedef.PodInfo) error {
|
|
+ if podInfo.Offline() {
|
|
+ return dynMem.dynMemoryAdapter.setOfflinePod(podInfo.Path)
|
|
+ }
|
|
+ return nil
|
|
+}
|
|
+
|
|
+// UpdatePod to deal the pod update event.
|
|
+func (dynMem *DynMemory) UpdatePod(old, new *typedef.PodInfo) error {
|
|
+ if new.Offline() {
|
|
+ return dynMem.dynMemoryAdapter.setOfflinePod(new.Path)
|
|
+ }
|
|
+ return nil
|
|
+}
|
|
+
|
|
// newAdapter to create adapter of dyn memory.
|
|
func newAdapter(policy string) DynMemoryAdapter {
|
|
switch policy {
|
|
diff --git a/pkg/services/dynmemory/fssr.go b/pkg/services/dynmemory/fssr.go
|
|
index 9fe4042..e23a4bc 100644
|
|
--- a/pkg/services/dynmemory/fssr.go
|
|
+++ b/pkg/services/dynmemory/fssr.go
|
|
@@ -9,6 +9,7 @@ import (
|
|
|
|
"isula.org/rubik/pkg/api"
|
|
"isula.org/rubik/pkg/common/constant"
|
|
+ "isula.org/rubik/pkg/common/log"
|
|
"isula.org/rubik/pkg/common/util"
|
|
"isula.org/rubik/pkg/core/typedef"
|
|
"isula.org/rubik/pkg/core/typedef/cgroup"
|
|
@@ -30,71 +31,76 @@ type fssrDynMemAdapter struct {
|
|
memTotal int64
|
|
memHigh int64
|
|
reservedMem int64
|
|
- api api.Viewer
|
|
count int64
|
|
+ viewer api.Viewer
|
|
}
|
|
|
|
-// initFssrDynMemAdapter function
|
|
+// initFssrDynMemAdapter initializes a new fssrDynMemAdapter struct.
|
|
func initFssrDynMemAdapter() *fssrDynMemAdapter {
|
|
if total, err := getFieldMemory("MemTotal"); err == nil && total > 0 {
|
|
return &fssrDynMemAdapter{
|
|
memTotal: total,
|
|
memHigh: total * 8 / 10,
|
|
- reservedMem: total * 8 / 10,
|
|
+ reservedMem: total * 1 / 10,
|
|
+ count: 0,
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
-// preStart function
|
|
-func (f *fssrDynMemAdapter) preStart(api api.Viewer) error {
|
|
- f.api = api
|
|
+// preStart initializes the fssrDynMemAdapter with the provided viewer and
|
|
+// deals with any existing pods.
|
|
+func (f *fssrDynMemAdapter) preStart(viewer api.Viewer) error {
|
|
+ f.viewer = viewer
|
|
return f.dealExistedPods()
|
|
}
|
|
|
|
-// getInterval function
|
|
+// getInterval returns the fssrInterval value.
|
|
func (f *fssrDynMemAdapter) getInterval() int {
|
|
return fssrInterval
|
|
}
|
|
|
|
-// dynadjust function
|
|
+// dynamicAdjust adjusts the memory allocation of the fssrDynMemAdapter by
|
|
+// increasing or decreasing the amount of memory reserved for offline pods
|
|
+// based on the current amount of free memory available on the system.
|
|
func (f *fssrDynMemAdapter) dynamicAdjust() {
|
|
var freeMem int64
|
|
var err error
|
|
if freeMem, err = getFieldMemory("MemFree"); err != nil {
|
|
return
|
|
}
|
|
+
|
|
+ var memHigh int64 = 0
|
|
if freeMem > 2*f.reservedMem {
|
|
if f.count < fssrIntervalCount {
|
|
f.count++
|
|
return
|
|
}
|
|
- memHigh := f.memHigh + f.memTotal/100
|
|
+ // no risk of overflow
|
|
+ memHigh = f.memHigh + f.memTotal/100
|
|
if memHigh > f.memTotal*8/10 {
|
|
memHigh = f.memTotal * 8 / 10
|
|
}
|
|
- if memHigh != f.memHigh {
|
|
- f.memHigh = memHigh
|
|
- f.adjustOfflinePodHighMemory()
|
|
- }
|
|
} else if freeMem < f.reservedMem {
|
|
- memHigh := f.memHigh - f.memTotal/10
|
|
+ memHigh = f.memHigh - f.memTotal/10
|
|
if memHigh < 0 {
|
|
return
|
|
}
|
|
if memHigh < f.memTotal*3/10 {
|
|
memHigh = f.memTotal * 3 / 10
|
|
}
|
|
- if memHigh != f.memHigh {
|
|
- f.memHigh = memHigh
|
|
- f.adjustOfflinePodHighMemory()
|
|
- }
|
|
}
|
|
+ if memHigh != f.memHigh {
|
|
+ f.memHigh = memHigh
|
|
+ f.adjustOfflinePodHighMemory()
|
|
+ }
|
|
+
|
|
f.count = 0
|
|
}
|
|
|
|
+// adjustOfflinePodHighMemory adjusts the memory.high of offline pods.
|
|
func (f *fssrDynMemAdapter) adjustOfflinePodHighMemory() error {
|
|
- pods := listOfflinePods(f.api)
|
|
+ pods := listOfflinePods(f.viewer)
|
|
for _, podInfo := range pods {
|
|
if err := setOfflinePodHighMemory(podInfo.Path, f.memHigh); err != nil {
|
|
return err
|
|
@@ -103,20 +109,18 @@ func (f *fssrDynMemAdapter) adjustOfflinePodHighMemory() error {
|
|
return nil
|
|
}
|
|
|
|
-// dealExistedPods function
|
|
+// dealExistedPods handles offline pods by setting their memory.high and memory.high_async_ratio
|
|
func (f *fssrDynMemAdapter) dealExistedPods() error {
|
|
- pods := listOfflinePods(f.api)
|
|
+ pods := listOfflinePods(f.viewer)
|
|
for _, podInfo := range pods {
|
|
- if err := setOfflinePodHighMemory(podInfo.Path, f.memHigh); err != nil {
|
|
- return err
|
|
- }
|
|
- if err := setOfflinePodHighAsyncRatio(podInfo.Path, highRatio); err != nil {
|
|
- return err
|
|
+ if err := f.setOfflinePod(podInfo.Path); err != nil {
|
|
+ log.Errorf("set fssr of offline pod[%v] error:%v", podInfo.UID, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
+// listOfflinePods returns a map of offline PodInfo objects.
|
|
func listOfflinePods(viewer api.Viewer) map[string]*typedef.PodInfo {
|
|
offlineValue := "true"
|
|
return viewer.ListPodsWithOptions(func(pi *typedef.PodInfo) bool {
|
|
@@ -124,23 +128,35 @@ func listOfflinePods(viewer api.Viewer) map[string]*typedef.PodInfo {
|
|
})
|
|
}
|
|
|
|
-func setOfflinePodHighMemory(podPath string, high int64) error {
|
|
- if err := cgroup.WriteCgroupFile(strconv.FormatUint(uint64(high), scale), memcgRootDir,
|
|
+// setOfflinePod sets the offline pod for the given path.
|
|
+func (f *fssrDynMemAdapter) setOfflinePod(path string) error {
|
|
+ if err := setOfflinePodHighAsyncRatio(path, highRatio); err != nil {
|
|
+ return err
|
|
+ }
|
|
+ return setOfflinePodHighMemory(path, f.memHigh)
|
|
+}
|
|
+
|
|
+// setOfflinePodHighMemory sets the high memory limit for the specified pod in the
|
|
+// cgroup memory
|
|
+func setOfflinePodHighMemory(podPath string, memHigh int64) error {
|
|
+ if err := cgroup.WriteCgroupFile(strconv.FormatUint(uint64(memHigh), scale), memcgRootDir,
|
|
podPath, highMemFile); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
-func setOfflinePodHighAsyncRatio(podPath string, ratio uint64) error {
|
|
- if err := cgroup.WriteCgroupFile(strconv.FormatUint(ratio, scale), memcgRootDir,
|
|
+// setOfflinePodHighAsyncRatio sets the high memory async ratio for a pod in an offline state.
|
|
+func setOfflinePodHighAsyncRatio(podPath string, ratio uint) error {
|
|
+ if err := cgroup.WriteCgroupFile(strconv.FormatUint(uint64(ratio), scale), memcgRootDir,
|
|
podPath, highMemAsyncRatioFile); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
-// getFieldMemory function
|
|
+// getFieldMemory retrieves the amount of memory used by a certain field in the
|
|
+// memory information file.
|
|
func getFieldMemory(field string) (int64, error) {
|
|
if !util.PathExist(memInfoFile) {
|
|
return 0, fmt.Errorf("%v: no such file or diretory", memInfoFile)
|
|
--
|
|
2.41.0
|
|
|