scheduler: make schedtag prefer and avoid strategy work

This commit is contained in:
Zexi Li
2018-12-12 19:56:21 +08:00
parent f162ff5844
commit 2c5ed4b360
17 changed files with 642 additions and 196 deletions
@@ -6,8 +6,10 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/scheduler/algorithm/plugin"
"yunion.io/x/onecloud/pkg/scheduler/api"
"yunion.io/x/onecloud/pkg/scheduler/core"
"yunion.io/x/onecloud/pkg/scheduler/core/score"
"yunion.io/x/onecloud/pkg/scheduler/db/models"
"yunion.io/x/onecloud/pkg/util/conditionparser"
)
@@ -23,6 +25,7 @@ import (
// the host is available.
type AggregatePredicate struct {
BasePredicate
plugin.BasePlugin
AggregateHosts hostsAggregatesMap
RequireAggregates []api.Aggregate
ExcludeAggregates []api.Aggregate
@@ -193,33 +196,6 @@ func getHostAggregateCount(inAggs []api.Aggregate, hAggs []*models.Aggregate, st
return
}
func (p *AggregatePredicate) OnSelect(u *core.Unit, c core.Candidater) bool {
hostAggs, ok := p.AggregateHosts[c.IndexKey()]
if !ok {
return true
}
avoidCountMap := getHostAggregateCount(p.AvoidAggregates, hostAggs, api.AggregateStrategyAvoid)
preferCountMap := getHostAggregateCount(p.PreferAggregates, hostAggs, api.AggregateStrategyPrefer)
setScore := func(aggCountMap map[string]int, postiveScore bool) {
stepScore := core.PriorityStep
if !postiveScore {
stepScore = -stepScore
}
for n, count := range aggCountMap {
u.IncreaseScore(c.IndexKey(), n, count*stepScore)
}
}
setScore(avoidCountMap, false)
setScore(preferCountMap, true)
return true
}
func (p *AggregatePredicate) OnSelectEnd(u *core.Unit, c core.Candidater, count int64) {}
func (p *AggregatePredicate) Execute(u *core.Unit, c core.Candidater) (bool, []core.PredicateFailureReason, error) {
h := NewPredicateHelper(p, u, c)
@@ -281,3 +257,29 @@ func (p *AggregatePredicate) exec(h *PredicateHelper) string {
return ""
}
func (p *AggregatePredicate) OnPriorityEnd(u *core.Unit, c core.Candidater) {
hostAggs, ok := p.AggregateHosts[c.IndexKey()]
if !ok {
return
}
avoidCountMap := getHostAggregateCount(p.AvoidAggregates, hostAggs, api.AggregateStrategyAvoid)
preferCountMap := getHostAggregateCount(p.PreferAggregates, hostAggs, api.AggregateStrategyPrefer)
setScore := func(aggCountMap map[string]int, postiveScore bool) {
stepScore := core.PriorityStep
if !postiveScore {
stepScore = -stepScore
}
for n, count := range aggCountMap {
u.SetFrontScore(
c.IndexKey(),
score.NewScore(score.TScore(count*stepScore), n),
)
}
}
setScore(preferCountMap, true)
setScore(avoidCountMap, false)
}
@@ -7,6 +7,7 @@ import (
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/scheduler/algorithm/plugin"
"yunion.io/x/onecloud/pkg/scheduler/algorithm/predicates"
"yunion.io/x/onecloud/pkg/scheduler/api"
"yunion.io/x/onecloud/pkg/scheduler/core"
@@ -14,6 +15,7 @@ import (
type NetworkPredicate struct {
BasePredicate
plugin.BasePlugin
SelectedNetworks sync.Map
}
@@ -141,11 +143,3 @@ func (p *NetworkPredicate) Execute(u *core.Unit, c core.Candidater) (bool, []cor
return h.GetResult()
}
func (p *NetworkPredicate) OnSelect(u *core.Unit, c core.Candidater) bool {
u.SetFiltedData(c.IndexKey(), "networks", &p.SelectedNetworks)
return true
}
func (p *NetworkPredicate) OnSelectEnd(u *core.Unit, c core.Candidater, count int64) {
}
@@ -3,14 +3,17 @@ package guest
import (
"fmt"
"yunion.io/x/onecloud/pkg/scheduler/algorithm/plugin"
"yunion.io/x/onecloud/pkg/scheduler/algorithm/predicates"
"yunion.io/x/onecloud/pkg/scheduler/core"
"yunion.io/x/onecloud/pkg/scheduler/core/score"
)
// GroupPredicate filter the packet based on the label information,
// the same group of guests should avoid schedule on same host.
type GroupPredicate struct {
predicates.BasePredicate
plugin.BasePlugin
ExcludeGroups []string
RequireGroups []string
@@ -47,33 +50,6 @@ func (p *GroupPredicate) PreExecute(u *core.Unit, cs []core.Candidater) (bool, e
return true, nil
}
func (p *GroupPredicate) OnSelect(u *core.Unit, c core.Candidater) bool {
if len(p.ExcludeGroups) > 0 {
return false
}
if len(p.RequireGroups) > 0 {
// TODO: what?
}
if len(p.AvoidGroups) > 0 {
u.IncreaseScore(c.IndexKey(),
p.Name()+":avoid", -core.PriorityStep*len(p.AvoidGroups),
)
}
if len(p.PreferGroups) > 0 {
u.IncreaseScore(c.IndexKey(),
p.Name()+":prefer", core.PriorityStep*len(p.PreferGroups),
)
}
return true
}
func (p *GroupPredicate) OnSelectEnd(u *core.Unit, c core.Candidater, count int64) {
}
func (p *GroupPredicate) Execute(u *core.Unit, c core.Candidater) (bool, []core.PredicateFailureReason, error) {
h := predicates.NewPredicateHelper(p, u, c)
@@ -101,3 +77,23 @@ func (p *GroupPredicate) Execute(u *core.Unit, c core.Candidater) (bool, []core.
return h.GetResult()
}
func (p *GroupPredicate) OnPriorityEnd(u *core.Unit, c core.Candidater) {
if len(p.AvoidGroups) > 0 {
u.SetFrontScore(
c.IndexKey(),
score.NewScore(
score.TScore(-core.PriorityStep*len(p.AvoidGroups)),
p.Name()+":avoid",
))
}
if len(p.PreferGroups) > 0 {
u.SetFrontScore(
c.IndexKey(),
score.NewScore(
score.TScore(core.PriorityStep*len(p.PreferGroups)),
p.Name()+":prefer",
))
}
}
@@ -5,12 +5,14 @@ import (
"strings"
"sync"
"yunion.io/x/pkg/util/sets"
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/scheduler/algorithm/plugin"
"yunion.io/x/onecloud/pkg/scheduler/algorithm/predicates"
"yunion.io/x/onecloud/pkg/scheduler/api"
"yunion.io/x/onecloud/pkg/scheduler/core"
networks "yunion.io/x/onecloud/pkg/scheduler/db/models"
"yunion.io/x/pkg/util/sets"
"yunion.io/x/pkg/utils"
)
// NetworkPredicate will filter the current network information with
@@ -18,6 +20,7 @@ import (
// randomly match the available network resources.
type NetworkPredicate struct {
predicates.BasePredicate
plugin.BasePlugin
SelectedNetworks sync.Map
}
@@ -105,10 +108,6 @@ func (p *NetworkPredicate) Execute(u *core.Unit, c core.Candidater) (bool, []cor
p.SelectedNetworks.Store(n.ID, counter.GetCount())
counters.Add(counter)
found = true
if counters.GetCount() >= d.Count {
break
}
} else {
fullErrMsgs = append(fullErrMsgs,
fmt.Sprintf("%s: %s", n.ID, strings.Join(errMsgs, ",")),
@@ -202,11 +201,3 @@ func (p *NetworkPredicate) Execute(u *core.Unit, c core.Candidater) (bool, []cor
return h.GetResult()
}
func (p *NetworkPredicate) OnSelect(u *core.Unit, c core.Candidater) bool {
u.SetFiltedData(c.IndexKey(), "networks", &p.SelectedNetworks)
return true
}
func (p *NetworkPredicate) OnSelectEnd(u *core.Unit, c core.Candidater, count int64) {
}