opt(scheduler): better sort for hosts when selectHost

This commit is contained in:
rainzm
2020-07-24 14:59:58 +08:00
committed by Rain Zheng
parent 7e55869cad
commit ed4847dffc
2 changed files with 48 additions and 12 deletions
+2 -2
View File
@@ -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),
@@ -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"`
+46 -10
View File
@@ -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 {
@@ -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++ {
@@ -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)
@@ -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 {