Skip to content

Commit

Permalink
opt(scheduler): better sort for hosts when selectHost
Browse files Browse the repository at this point in the history
  • Loading branch information
rainzm committed Aug 1, 2020
1 parent 88497da commit 49b0a01
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 12 deletions.
4 changes: 2 additions & 2 deletions pkg/scheduler/core/generic_scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func newSchedResultByCtx(u *Unit, count int64, c Candidater) *SchedResultItem {
Count: count,
Capacity: u.GetCapacity(id),
Name: c.Getter().Name(),
Score: u.GetScore(id).String(),
Score: u.GetScore(id),
Data: u.GetFiltedData(id, count),
Candidater: c,
AllocatedResource: u.GetAllocatedResource(id),
Expand Down Expand Up @@ -244,7 +244,7 @@ type SchedResultItem struct {
Count int64 `json:"count"`
Data map[string]interface{} `json:"data"`
Capacity int64 `json:"capacity"`
Score string `json:"score"`
Score Score `json:"score"`

CapacityDetails map[string]int64 `json:"capacity_details"`
ScoreDetails string `json:"score_details"`
Expand Down
56 changes: 46 additions & 10 deletions pkg/scheduler/manager/instancegroup_select.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"yunion.io/x/onecloud/pkg/scheduler/api"
"yunion.io/x/onecloud/pkg/scheduler/cache/candidate"
"yunion.io/x/onecloud/pkg/scheduler/core"
"yunion.io/x/onecloud/pkg/scheduler/core/score"
)

func transToInstanceGroupSchedResult(result *core.SchedResultItemList, schedInfo *api.SchedInfo) *schedapi.ScheduleOutput {
Expand Down Expand Up @@ -55,6 +56,19 @@ type sSchedResultItem struct {
backupCount int64
}

func (item *sSchedResultItem) minInstanceGroupCapacity(groupSet map[string]*models.SGroup) int64 {
var mincapa int64 = -1
for id, capa := range item.instanceGroupCapacity {
if _, ok := groupSet[id]; !ok {
continue
}
if mincapa == -1 || capa < mincapa {
mincapa = capa
}
}
return mincapa
}

func buildHosts(result *core.SchedResultItemList, groups map[string]*models.SGroup) []*sSchedResultItem {
hosts := make([]*sSchedResultItem, result.Data.Len())
for i := 0; i < len(result.Data); i++ {
Expand All @@ -78,30 +92,52 @@ func buildHosts(result *core.SchedResultItemList, groups map[string]*models.SGro
instanceGroupCapacity: igCapacity,
}
}
sortHosts(hosts, nil)
return hosts
}

// sortHost sorts the host for guest that is the backup one of the high-availability guest
// if isBackup is true and the master one if isBackup is false.
func sortHosts(hosts []*sSchedResultItem, isBackup *bool) {
func sortHosts(hosts []*sSchedResultItem, guestInfo *sGuestInfo, isBackup *bool) {
sortIndexi, sortIndexj := make([]int64, 4), make([]int64, 4)
sort.Slice(hosts, func(i, j int) bool {
var counti, countj int64
switch {
case isBackup == nil:
counti, countj = hosts[i].Count, hosts[j].Count
sortIndexi[0], sortIndexj[0] = hosts[i].Count, hosts[j].Count
case *isBackup:
counti, countj = hosts[i].backupCount, hosts[j].backupCount
sortIndexi[0], sortIndexj[0] = hosts[i].backupCount, hosts[j].backupCount
default:
counti, countj = hosts[i].masterCount, hosts[j].masterCount
sortIndexi[0], sortIndexj[0] = hosts[i].masterCount, hosts[j].masterCount
}
if counti == countj {
return hosts[i].Capacity > hosts[j].Capacity
sortIndexi[1], sortIndexj[1] = hosts[i].Count, hosts[j].Count
sortIndexi[2], sortIndexj[2] = -(hosts[i].minInstanceGroupCapacity(guestInfo.instanceGroupsDetail)), -(hosts[j].minInstanceGroupCapacity(guestInfo.instanceGroupsDetail))
sortIndexi[3], sortIndexj[3] = scoreNormalization(hosts[i].Score, hosts[j].Score)
sortIndexi[4], sortIndexj[4] = -(hosts[i].Capacity), -(hosts[j].Capacity)
for i := 0; i < 5; i++ {
if sortIndexi[i] == sortIndexj[i] {
continue
}
return sortIndexi[i] < sortIndexj[i]
}
return counti < countj
return true
})
}

// scoreNormalization compare the value of s1 and s2.
// If s1 is less than s2, return 1, 0 which means s2 is better than s1.
func scoreNormalization(s1, s2 core.Score) (int64, int64) {
sb1, sb2 := s1.ScoreBucket, s2.ScoreBucket
preferLess := score.PreferLess(sb1, sb2)
avoidLess := score.AvoidLess(sb1, sb2)
normalLess := score.AvoidLess(sb1, sb2)
if preferLess || normalLess {
return 1, 0
}
if avoidLess {
return 0, 1
}
return 0, 0
}

// buildWireHosts classify hosts according to their wire
func buildWireHosts(hosts []*sSchedResultItem) map[string][]*sSchedResultItem {
wireHostMap := make(map[string][]*sSchedResultItem)
Expand Down Expand Up @@ -288,7 +324,7 @@ func unMarkHostUsed(host *sSchedResultItem, guestInfo sGuestInfo, isBackup *bool
// If forced is true, all instanceGroups will be forced.
// Otherwise, the instanceGroups with ForceDispersion 'false' will be unforced.
func selectHost(hosts []*sSchedResultItem, guestInfo sGuestInfo, isBackup *bool, forced bool) *sSchedResultItem {
sortHosts(hosts, isBackup)
sortHosts(hosts, &guestInfo, isBackup)
var idx = -1
if len(guestInfo.preferHost) > 0 {
if idx = hostsIndex(guestInfo.preferHost, hosts); idx < 0 {
Expand Down

0 comments on commit 49b0a01

Please sign in to comment.