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
+12
View File
@@ -0,0 +1,12 @@
package plugin
import (
"yunion.io/x/onecloud/pkg/scheduler/core"
)
type BasePlugin struct{}
// Customize priority
func (p BasePlugin) OnPriorityEnd(u *core.Unit, c core.Candidater) {}
func (p BasePlugin) OnSelectEnd(u *core.Unit, c core.Candidater, count int64) {}
@@ -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) {
}
@@ -27,7 +27,7 @@ func (p *AvoidSameHostPriority) Map(u *core.Unit, c core.Candidater) (core.HostP
ownerTenantID := u.SchedData().OwnerTenantID
if count, ok := hc.Tenants[ownerTenantID]; ok && count > 0 {
h.SetScore(-50 * int(count))
h.SetFrontRawScore(-1 * int(count))
}
return h.GetResult()
@@ -21,7 +21,7 @@ func (p *CapacityPriority) Map(u *core.Unit, c core.Candidater) (core.HostPriori
h := priorities.NewPriorityHelper(p, u, c)
capacity := u.GetCapacity(c.IndexKey())
h.SetScore(50 * int(capacity))
h.SetRawScore(int(capacity))
return h.GetResult()
}
@@ -27,8 +27,8 @@ func (p *CreatingPriority) Map(u *core.Unit, c core.Candidater) (core.HostPriori
}
if hc.CreatingGuestCount > 0 {
score := -int(hc.CreatingGuestCount) * 20
h.SetScore(score)
score := -int(hc.CreatingGuestCount)
h.SetFrontScore(score)
}
return h.GetResult()
@@ -3,6 +3,7 @@ package guest
import (
"yunion.io/x/onecloud/pkg/scheduler/algorithm/priorities"
"yunion.io/x/onecloud/pkg/scheduler/core"
"yunion.io/x/onecloud/pkg/scheduler/core/score"
)
type LowLoadPriority struct {
@@ -28,8 +29,12 @@ func (p *LowLoadPriority) Map(u *core.Unit, c core.Candidater) (core.HostPriorit
cpuCommitRate := float64(hc.RunningCPUCount) / float64(hc.TotalCPUCount)
memCommitRate := float64(hc.RunningMemSize) / float64(hc.TotalMemSize)
if cpuCommitRate < 0.5 && memCommitRate < 0.5 {
score := 20 * (1 - cpuCommitRate - memCommitRate)
score := 10 * (1 - cpuCommitRate - memCommitRate)
h.SetScore(int(score))
}
return h.GetResult()
}
func (p *LowLoadPriority) ScoreIntervals() score.Intervals {
return score.NewIntervals(0, 1, 5)
}
@@ -1,23 +1,18 @@
package priorities
import (
"math"
"yunion.io/x/onecloud/pkg/scheduler/algorithm"
"yunion.io/x/onecloud/pkg/scheduler/cache/candidate"
"yunion.io/x/onecloud/pkg/scheduler/core"
"yunion.io/x/onecloud/pkg/scheduler/core/score"
)
func aggPriority(x float64) float64 {
return math.Log(x + math.Sqrt(x*x+1))
}
// PriorityHelper is a struct that as a base interface for all priorities.
type PriorityHelper struct {
priority core.Priority
unit *core.Unit
Candidate core.Candidater
score int
score score.SScore
err error
}
@@ -29,9 +24,38 @@ func NewPriorityHelper(p core.Priority, u *core.Unit, c core.Candidater) *Priori
}
}
func (h *PriorityHelper) SetScore(score int) {
h.score = score
h.unit.SetScore(h.Candidate.IndexKey(), h.priority.Name(), score)
func (h *PriorityHelper) setIntervalScore(val int) score.SScore {
h.score = score.NewScore(
h.priority.ScoreIntervals().ToScore(int64(val)),
h.priority.Name())
return h.score
}
func (h *PriorityHelper) setRawScore(val int) score.SScore {
h.score = score.NewScore(
score.TScore(val),
h.priority.Name())
return h.score
}
func (h *PriorityHelper) SetScore(val int) {
h.setIntervalScore(val)
h.unit.SetScore(h.Candidate.IndexKey(), h.score)
}
func (h *PriorityHelper) SetFrontScore(val int) {
h.setIntervalScore(val)
h.unit.SetFrontScore(h.Candidate.IndexKey(), h.score)
}
func (h *PriorityHelper) SetRawScore(val int) {
h.setRawScore(val)
h.unit.SetScore(h.Candidate.IndexKey(), h.score)
}
func (h *PriorityHelper) SetFrontRawScore(val int) {
h.setRawScore(val)
h.unit.SetFrontScore(h.Candidate.IndexKey(), h.score)
}
func (h *PriorityHelper) SetError(err error) {
@@ -41,7 +65,6 @@ func (h *PriorityHelper) SetError(err error) {
func (h *PriorityHelper) GetResult() (core.HostPriority, error) {
return core.HostPriority{
Host: h.Candidate.IndexKey(),
Score: h.score,
Candidate: h.Candidate,
}, h.err
}
@@ -71,3 +94,7 @@ func (b *BasePriority) Name() string {
func (b *BasePriority) HostCandidate(c core.Candidater) (*candidate.HostDesc, error) {
return algorithm.ToHostCandidate(c)
}
func (b *BasePriority) ScoreIntervals() score.Intervals {
return score.NewIntervals(0, 1, 2)
}