Skip to content

Commit

Permalink
feat: calculate profits
Browse files Browse the repository at this point in the history
Signed-off-by: Gaius <[email protected]>
  • Loading branch information
gaius-qi committed Nov 18, 2021
1 parent b235447 commit 15d314d
Show file tree
Hide file tree
Showing 8 changed files with 329 additions and 205 deletions.
7 changes: 7 additions & 0 deletions pkg/util/mathutils/math_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@
package mathutils

import (
"math"
"strconv"
)

const float64EqualityThreshold = 1e-9

func MaxInt(a, b int) int {
if a < b {
return a
Expand Down Expand Up @@ -84,3 +87,7 @@ func IsInteger(value string) bool {

return false
}

func EqualFloat64(a, b float64) bool {
return math.Abs(a-b) <= float64EqualityThreshold
}
24 changes: 4 additions & 20 deletions scheduler/core/evaluator/evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const (

type Evaluator interface {
// Evaluate todo Normalization
Evaluate(parent *supervisor.Peer, child *supervisor.Peer) float64
Evaluate(parent *supervisor.Peer, child *supervisor.Peer, taskPieceCount int32) float64

// NeedAdjustParent determine whether the peer needs a new parent node
NeedAdjustParent(peer *supervisor.Peer) bool
Expand All @@ -42,32 +42,16 @@ type Evaluator interface {
IsBadNode(peer *supervisor.Peer) bool
}

type evaluator struct {
strategy Evaluator
}

func New(algorithm string) Evaluator {
switch algorithm {
case PluginAlgorithm:
if plugin, err := LoadPlugin(); err == nil {
return &evaluator{strategy: plugin}
return plugin
}
// TODO Implement MLAlgorithm
case MLAlgorithm, DefaultAlgorithm:
return &evaluator{strategy: NewEvaluatorBase()}
return NewEvaluatorBase()
}

return &evaluator{strategy: NewEvaluatorBase()}
}

func (e *evaluator) Evaluate(dst *supervisor.Peer, src *supervisor.Peer) float64 {
return e.strategy.Evaluate(dst, src)
}

func (e *evaluator) NeedAdjustParent(peer *supervisor.Peer) bool {
return e.strategy.NeedAdjustParent(peer)
}

func (e *evaluator) IsBadNode(peer *supervisor.Peer) bool {
return e.strategy.IsBadNode(peer)
return NewEvaluatorBase()
}
93 changes: 56 additions & 37 deletions scheduler/core/evaluator/evaluator_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package evaluator

import (
"math"
"math/big"
"strings"

Expand All @@ -29,33 +28,44 @@ import (
)

const (
// If the number of samples is greater than or equal to 10, it is close to the normal distribution
normalDistributionLen = 10
// Finished piece weight
finishedPieceWeight float64 = 0.3

// When costs len is greater than or equal to 2, the last cost can be compared and calculated
minAvailableCostLen = 2
)
// Free load weight
freeLoadWeight = 0.2

// Host uuid weight
hostUUIDWeight = 0.2

const (
// IDC affinity weight
idcAffinityWeight float64 = 0.5
idcAffinityWeight = 0.15

// NetTopology affinity weight
netTopologyAffinityWeight float64 = 0.3
netTopologyAffinityWeight = 0.08

// Location affinity weight
locationAffinityWeight float64 = 0.2
locationAffinityWeight = 0.07
)

const (
// Maximum score
maxScore float64 = 1

// Minimum score
minScore float64 = 0
minScore = 0
)

const (
// If the number of samples is greater than or equal to 10,
// it is close to the normal distribution
normalDistributionLen = 10

// When costs len is greater than or equal to 2,
// the last cost can be compared and calculated
minAvailableCostLen = 2

// Maximum number of elements
maxElementLen int = 5
maxElementLen = 5
)

type evaluatorBase struct{}
Expand All @@ -65,7 +75,7 @@ func NewEvaluatorBase() Evaluator {
}

// The larger the value after evaluation, the higher the priority
func (eb *evaluatorBase) Evaluate(parent *supervisor.Peer, child *supervisor.Peer) float64 {
func (eb *evaluatorBase) Evaluate(parent *supervisor.Peer, child *supervisor.Peer, taskPieceCount int32) float64 {
// If the SecurityDomain of hosts exists but is not equal,
// it cannot be scheduled as a parent
if parent.Host.SecurityDomain != "" &&
Expand All @@ -74,50 +84,59 @@ func (eb *evaluatorBase) Evaluate(parent *supervisor.Peer, child *supervisor.Pee
return minScore
}

// Profits has the highest priority, FreeLoad Percent and Affinity have the same priority
return calculateProfits(parent, child) + calculateFreeLoadPercent(parent.Host) + calculateAffinity(parent, child)
return finishedPieceWeight*calculatePieceScore(parent, child, taskPieceCount) +
freeLoadWeight*calculateFreeLoadScore(parent.Host) +
hostUUIDWeight*calculateHostUUIDScore(parent.Host, child.Host) +
idcAffinityWeight*calculateIDCAffinityScore(parent.Host, child.Host) +
netTopologyAffinityWeight*calculateMultiElementAffinityScore(parent.Host.NetTopology, child.Host.NetTopology) +
locationAffinityWeight*calculateMultiElementAffinityScore(parent.Host.Location, child.Host.Location)
}

// calculateProfits 0.0~unlimited larger and better
func calculateProfits(dst *supervisor.Peer, src *supervisor.Peer) float64 {
diff := dst.TotalPieceCount.Load() - src.TotalPieceCount.Load()
depth := dst.GetTreeDepth()
return float64(int(diff+1)*src.GetTreeNodeCount()) / math.Pow(float64(depth), 2)
// calculatePieceScore 0.0~unlimited larger and better
func calculatePieceScore(parent *supervisor.Peer, child *supervisor.Peer, taskPieceCount int32) float64 {
// If the total piece is determined, normalize the number of
// pieces downloaded by the parent node
if taskPieceCount > 0 {
finishedPieceCount := parent.TotalPieceCount.Load()
return float64(finishedPieceCount) / float64(taskPieceCount)
}

// Use the difference between the parent node and the child node to
// download the piece to roughly represent the piece score
parentFinishedPieceCount := parent.TotalPieceCount.Load()
childFinishedPieceCount := child.TotalPieceCount.Load()
return float64(parentFinishedPieceCount - childFinishedPieceCount)
}

// calculateFreeLoadPercent 0.0~1.0 larger and better
func calculateFreeLoadPercent(host *supervisor.Host) float64 {
// calculateFreeLoadScore 0.0~1.0 larger and better
func calculateFreeLoadScore(host *supervisor.Host) float64 {
load := host.CurrentUploadLoad.Load()
totalLoad := host.TotalUploadLoad
return float64((totalLoad - load)) / float64(totalLoad)
return float64(totalLoad-load) / float64(totalLoad)
}

// calculateAffinity 0.0~1.0 larger and better
func calculateAffinity(dst *supervisor.Peer, src *supervisor.Peer) float64 {
// If the host is equal, it means that the same host downloads the same peer
// calculateHostUUIDScore 0.0~1.0 larger and better
func calculateHostUUIDScore(dst, src *supervisor.Host) float64 {
// If the host uuid is equal, it means that the same host downloads the same peer
// and the host is preferentially scheduled
if strings.Compare(dst.Host.UUID, src.Host.UUID) == 0 {
if strings.Compare(dst.UUID, src.UUID) == 0 {
return maxScore
}

// Affinity includes three features, the specific values of the features are IDC, NetTopology and Location.
// Based on three features and specific weights, the affinity value between 0 and 1 can be calculated.
return calculateIDCAffinity(dst.Host.IDC, src.Host.IDC)*idcAffinityWeight +
calculateMultiElementAffinity(dst.Host.NetTopology, src.Host.NetTopology)*netTopologyAffinityWeight +
calculateMultiElementAffinity(dst.Host.Location, src.Host.Location)*locationAffinityWeight
return minScore
}

// calculateIDCAffinity 0.0~1.0 larger and better
func calculateIDCAffinity(dst, src string) float64 {
if dst != "" && src != "" && strings.Compare(dst, src) == 0 {
// calculateIDCAffinityScore 0.0~1.0 larger and better
func calculateIDCAffinityScore(dst, src *supervisor.Host) float64 {
if dst.IDC != "" && src.IDC != "" && strings.Compare(dst.IDC, src.IDC) == 0 {
return maxScore
}

return minScore
}

// calculateMultiElementAffinity 0.0~1.0 larger and better
func calculateMultiElementAffinity(dst, src string) float64 {
// calculateMultiElementAffinityScore 0.0~1.0 larger and better
func calculateMultiElementAffinityScore(dst, src string) float64 {
if dst == "" || src == "" {
return minScore
}
Expand Down
Loading

0 comments on commit 15d314d

Please sign in to comment.