mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
opt(scheduler): better sort for hosts when selectHost
This commit is contained in:
@@ -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"`
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user