diff --git a/pkg/schedule/placement/fit.go b/pkg/schedule/placement/fit.go index ed940160bbd..7d447a72926 100644 --- a/pkg/schedule/placement/fit.go +++ b/pkg/schedule/placement/fit.go @@ -119,6 +119,7 @@ type RuleFit struct { // IsolationScore indicates at which level of labeling these Peers are // isolated. A larger value is better. IsolationScore float64 `json:"isolation-score"` + WitnessScore int `json:"witness-score"` // stores is the stores that the peers are placed in. stores []*core.StoreInfo } @@ -151,6 +152,10 @@ func compareRuleFit(a, b *RuleFit) int { return -1 case a.IsolationScore > b.IsolationScore: return 1 + case a.WitnessScore > b.WitnessScore: + return -1 + case a.WitnessScore < b.WitnessScore: + return 1 default: return 0 } @@ -345,7 +350,7 @@ func (w *fitWorker) updateOrphanPeers(index int) { } func newRuleFit(rule *Rule, peers []*fitPeer, supportWitness bool) *RuleFit { - rf := &RuleFit{Rule: rule, IsolationScore: isolationScore(peers, rule.LocationLabels)} + rf := &RuleFit{Rule: rule, IsolationScore: isolationScore(peers, rule.LocationLabels), WitnessScore: witnessScore(peers, supportWitness && rule.IsWitness)} for _, p := range peers { rf.Peers = append(rf.Peers, p.Peer) rf.stores = append(rf.stores, p.store) @@ -441,3 +446,14 @@ func stateScore(region *core.RegionInfo, peerID uint64) int { return 2 } } + +func witnessScore(peers []*fitPeer, fitWitness bool) int { + var score int + if !fitWitness || len(peers) == 0 { + return 0 + } + for _, p := range peers { + score += p.store.GetWitnessCount() + } + return score +}