volcano.sh/volcano@v1.9.0/pkg/scheduler/plugins/rescheduling/rescheduling.go (about) 1 /* 2 Copyright 2022 The Volcano 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 rescheduling 18 19 import ( 20 "time" 21 22 "github.com/mitchellh/mapstructure" 23 24 "k8s.io/klog/v2" 25 26 "volcano.sh/volcano/pkg/scheduler/api" 27 "volcano.sh/volcano/pkg/scheduler/framework" 28 ) 29 30 const ( 31 // PluginName indicates name of volcano scheduler plugin 32 PluginName = "rescheduling" 33 // DefaultInterval indicates the default interval rescheduling plugin works for 34 DefaultInterval = 5 * time.Minute 35 // DefaultMetricsPeriod indicates the default metrics period rescheduling plugin works for 36 DefaultMetricsPeriod = "5m" 37 // DefaultStrategy indicates the default strategy rescheduling plugin making use of 38 DefaultStrategy = "lowNodeUtilization" 39 ) 40 41 var ( 42 // Session contains all the data in session object which will be used for all the rescheduling package 43 Session *framework.Session 44 45 // RegisteredStrategyConfigs collects all the strategy configurations registered. 46 RegisteredStrategyConfigs map[string]interface{} 47 48 // VictimFn contains all the VictimTasksFn for registered the strategies 49 VictimFn map[string]api.VictimTasksFn 50 51 // MetricsPeriod indicates the metrics period will be used during this plugin. 5 minutes by default. 52 MetricsPeriod string 53 ) 54 55 func init() { 56 RegisteredStrategyConfigs = make(map[string]interface{}) 57 VictimFn = make(map[string]api.VictimTasksFn) 58 MetricsPeriod = "5m" 59 60 // register victim functions for all strategies here 61 VictimFn["lowNodeUtilization"] = victimsFnForLnu 62 } 63 64 type reschedulingPlugin struct { 65 // Arguments given for rescheduling plugin 66 pluginArguments framework.Arguments 67 } 68 69 // New function returns rescheduling plugin object 70 func New(arguments framework.Arguments) framework.Plugin { 71 return &reschedulingPlugin{ 72 pluginArguments: arguments, 73 } 74 } 75 76 // Name returns the name of rescheduling plugin 77 func (rp *reschedulingPlugin) Name() string { 78 return PluginName 79 } 80 81 func (rp *reschedulingPlugin) OnSessionOpen(ssn *framework.Session) { 82 klog.V(5).Infof("Enter rescheduling plugin ...") 83 defer klog.V(5).Infof("Leaving rescheduling plugin.") 84 85 // Parse all the rescheduling strategies and execution interval 86 Session = ssn 87 configs := NewReschedulingConfigs() 88 for _, tier := range ssn.Tiers { 89 for _, pluginOption := range tier.Plugins { 90 if pluginOption.Name == PluginName { 91 configs.parseArguments(pluginOption.Arguments) 92 break 93 } 94 } 95 } 96 97 if !timeToRun(configs.interval) { 98 klog.V(3).Infof("It is not the time to execute rescheduling strategies.") 99 return 100 } 101 102 // Get all strategies and register the victim functions for each strategy. 103 victimFns := make([]api.VictimTasksFn, 0) 104 for _, strategy := range configs.strategies { 105 if VictimFn[strategy.Name] != nil { 106 klog.V(4).Infof("strategy: %s\n", strategy.Name) 107 victimFns = append(victimFns, VictimFn[strategy.Name]) 108 } 109 } 110 ssn.AddVictimTasksFns(rp.Name(), victimFns) 111 } 112 113 func (rp *reschedulingPlugin) OnSessionClose(ssn *framework.Session) { 114 Session = nil 115 for k := range RegisteredStrategyConfigs { 116 delete(RegisteredStrategyConfigs, k) 117 } 118 } 119 120 // Configs is the struct for rescheduling plugin arguments 121 type Configs struct { 122 interval time.Duration 123 strategies []Strategy 124 } 125 126 // Strategy is the struct for rescheduling strategy 127 type Strategy struct { 128 Name string `json:"name"` 129 Params map[string]interface{} `json:"params"` 130 } 131 132 // NewReschedulingConfigs creates an object of rescheduling configurations with default configuration 133 func NewReschedulingConfigs() *Configs { 134 config := &Configs{ 135 interval: DefaultInterval, 136 strategies: []Strategy{ 137 { 138 Name: DefaultStrategy, 139 Params: DefaultLowNodeConf, 140 }, 141 }, 142 } 143 RegisteredStrategyConfigs[DefaultStrategy] = DefaultLowNodeConf 144 return config 145 } 146 147 // parseArguments parse all the rescheduling arguments 148 func (rc *Configs) parseArguments(arguments framework.Arguments) { 149 var intervalStr string 150 var err error 151 if intervalArg, ok := arguments["interval"]; ok { 152 intervalStr = intervalArg.(string) 153 } 154 rc.interval, err = time.ParseDuration(intervalStr) 155 if err != nil { 156 klog.V(4).Infof("Parse rescheduling interval failed. Reset the interval to 5m by default.") 157 rc.interval = DefaultInterval 158 } 159 if metricsPeriodArg, ok := arguments["metricsPeriod"]; ok { 160 MetricsPeriod = metricsPeriodArg.(string) 161 } 162 if MetricsPeriod == "" { 163 MetricsPeriod = DefaultMetricsPeriod 164 } 165 strategies, ok := arguments["strategies"] 166 if ok { 167 strategyArray, _ := strategies.([]interface{}) 168 if len(strategyArray) != 0 { 169 rc.strategies = rc.strategies[0:0] 170 } 171 for _, strategyInterface := range strategyArray { 172 strategy := new(Strategy) 173 err := mapstructure.Decode(strategyInterface, strategy) 174 if err != nil { 175 klog.V(3).Infof("Decode error: %s\n", err.Error()) 176 } else { 177 rc.strategies = append(rc.strategies, *strategy) 178 } 179 } 180 for k := range RegisteredStrategyConfigs { 181 delete(RegisteredStrategyConfigs, k) 182 } 183 for _, strategy := range rc.strategies { 184 RegisteredStrategyConfigs[strategy.Name] = strategy.Params 185 } 186 klog.V(3).Infof("RegisteredStrategyConfigs: %v\n", RegisteredStrategyConfigs) 187 } 188 for _, strategy := range rc.strategies { 189 klog.V(3).Infof("strategy: %s, params: %v\n", strategy.Name, strategy.Params) 190 } 191 }