Skip to content

Commit

Permalink
it can transfer leader between the different rule
Browse files Browse the repository at this point in the history
Signed-off-by: bufferflies <1045931706@qq.com>
  • Loading branch information
bufferflies committed Mar 21, 2023
1 parent 92772c9 commit 37c4313
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 3 deletions.
2 changes: 1 addition & 1 deletion pkg/schedule/filter/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ func (f *ruleFitFilter) Source(_ config.Config, _ *core.StoreInfo) *plan.Status
// the replaced store can match the source rule.
// RegionA:[1,2,3], move peer1 --> peer2 will not allow, because it's count not match the rule.
// but transfer role peer1 --> peer2, it will support.
func (f *ruleFitFilter) Target(options config.Config, store *core.StoreInfo) *plan.Status {
func (f *ruleFitFilter) Target(_ config.Config, store *core.StoreInfo) *plan.Status {
if f.oldFit.Replace(f.srcStore, store) {
return statusOK
}
Expand Down
16 changes: 14 additions & 2 deletions pkg/schedule/placement/fit.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,27 @@ type RegionFit struct {
func (f *RegionFit) Replace(srcStoreID uint64, dstStore *core.StoreInfo) bool {
fit := f.getRuleFitByStoreID(srcStoreID)
// check the target store is fit all constraints.
if fit == nil || !MatchLabelConstraints(dstStore, fit.Rule.LabelConstraints) {
if fit == nil {
return false
}

// the members of the rule are same, it shouldn't check the score.
// it is used to transfer role like transfer leader.
if fit.contain(dstStore.GetID()) {
return true
}

// it should be allowed to exchange role if both the source and target's rule role is same.
// e.g. transfer leader from store 1 to store 2, and store-1 and store-2 are both voter.
targetFit := f.getRuleFitByStoreID(dstStore.GetID())
if targetFit != nil && targetFit.Rule.Role == fit.Rule.Role {
return true
}

// the target store should be fit all constraints.
if !MatchLabelConstraints(dstStore, fit.Rule.LabelConstraints) {
return false
}

score := isolationStoreScore(srcStoreID, dstStore, fit.stores, fit.Rule.LocationLabels)
// restore the source store.
return fit.IsolationScore <= score
Expand Down
4 changes: 4 additions & 0 deletions pkg/schedule/placement/fit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ func TestReplace(t *testing.T) {
{"1111_leader,1121,1131", []string{"1/leader/host=host1+host2/host", "3/voter//host"}, 1111, 1121, true},
// replace failed when the leader is not match the leader constraint.
{"1111_leader,1121,1131", []string{"1/leader/host=host1+host2/host", "2/voter//host"}, 1111, 1131, false},

// transfer leader with different rule
{"1111_leader,1121,1131", []string{"1/voter/host=host1/host", "1/voter/host=host2/host", "1/voter/host=host3/host"}, 1111, 1121, true},
{"1111_leader,1121,1131", []string{"1/leader/host=host1/host", "1/voter/host=host2/host", "1/voter/host=host3/host"}, 1111, 1121, false},
}
for _, tc := range testCases {
region := makeRegion(tc.region)
Expand Down

0 comments on commit 37c4313

Please sign in to comment.