diff --git a/pkg/schedule/filter/region_filters.go b/pkg/schedule/filter/region_filters.go index 799cee7d90c..45a1c1b102e 100644 --- a/pkg/schedule/filter/region_filters.go +++ b/pkg/schedule/filter/region_filters.go @@ -173,7 +173,7 @@ type SnapshotSenderFilter struct { senders map[uint64]struct{} } -// NewSnapshotSendFilter returns creates a RegionFilter that filters regions with witness peer on the specific store. +// NewSnapshotSendFilter returns creates a RegionFilter that filters regions whose leader has sender limit on the specific store. // level should be set as same with the operator priority level. func NewSnapshotSendFilter(stores []*core.StoreInfo, level constant.PriorityLevel) RegionFilter { senders := make(map[uint64]struct{}) @@ -193,3 +193,28 @@ func (f *SnapshotSenderFilter) Select(region *core.RegionInfo) *plan.Status { } return statusRegionLeaderSendSnapshotThrottled } + +// SnapshotSenderFilter filer the region who's leader store reaches the limit. +type StoreRecentlySplitFilter struct { + recentlySplitStores map[uint64]struct{} +} + +// NewStoreRecentlySplitFilter returns creates a StoreRecentlySplitFilter that filters regions whose leader store has recently split region on it. +func NewStoreRecentlySplitFilter(stores []*core.StoreInfo) RegionFilter { + recentlySplitStores := make(map[uint64]struct{}) + for _, store := range stores { + if !store.HasRecentlySplitRegions() { + recentlySplitStores[store.GetID()] = struct{}{} + } + } + return &StoreRecentlySplitFilter{recentlySplitStores: recentlySplitStores} +} + +// Select returns ok if the region leader in the senders. +func (f *StoreRecentlySplitFilter) Select(region *core.RegionInfo) *plan.Status { + leaderStoreID := region.GetLeader().GetStoreId() + if _, ok := f.recentlySplitStores[leaderStoreID]; ok { + return statusOK + } + return statusStoreRecentlySplitRegions +} diff --git a/pkg/schedule/schedulers/balance_leader.go b/pkg/schedule/schedulers/balance_leader.go index ada32ab5c52..9f8fb09abbc 100644 --- a/pkg/schedule/schedulers/balance_leader.go +++ b/pkg/schedule/schedulers/balance_leader.go @@ -57,14 +57,13 @@ const ( var ( // WithLabelValues is a heavy operation, define variable to avoid call it every time. - balanceLeaderScheduleCounter = schedulerCounter.WithLabelValues(BalanceLeaderName, "schedule") - balanceLeaderNoLeaderRegionCounter = schedulerCounter.WithLabelValues(BalanceLeaderName, "no-leader-region") - balanceLeaderRegionHotCounter = schedulerCounter.WithLabelValues(BalanceLeaderName, "region-hot") - balanceLeaderNoTargetStoreCounter = schedulerCounter.WithLabelValues(BalanceLeaderName, "no-target-store") - balanceLeaderNoFollowerRegionCounter = schedulerCounter.WithLabelValues(BalanceLeaderName, "no-follower-region") - balanceLeaderSkipCounter = schedulerCounter.WithLabelValues(BalanceLeaderName, "skip") - balanceLeaderNewOpCounter = schedulerCounter.WithLabelValues(BalanceLeaderName, "new-operator") - balanceLeaderStoreRecentlySplitRegions = schedulerCounter.WithLabelValues(BalanceLeaderName, "source-recently-split-regions") + balanceLeaderScheduleCounter = schedulerCounter.WithLabelValues(BalanceLeaderName, "schedule") + balanceLeaderNoLeaderRegionCounter = schedulerCounter.WithLabelValues(BalanceLeaderName, "no-leader-region") + balanceLeaderRegionHotCounter = schedulerCounter.WithLabelValues(BalanceLeaderName, "region-hot") + balanceLeaderNoTargetStoreCounter = schedulerCounter.WithLabelValues(BalanceLeaderName, "no-target-store") + balanceLeaderNoFollowerRegionCounter = schedulerCounter.WithLabelValues(BalanceLeaderName, "no-follower-region") + balanceLeaderSkipCounter = schedulerCounter.WithLabelValues(BalanceLeaderName, "skip") + balanceLeaderNewOpCounter = schedulerCounter.WithLabelValues(BalanceLeaderName, "new-operator") ) type balanceLeaderSchedulerConfig struct { @@ -468,7 +467,8 @@ func (l *balanceLeaderScheduler) transferLeaderOut(solver *solver, collector *pl // the worst follower peer and transfers the leader. func (l *balanceLeaderScheduler) transferLeaderIn(solver *solver, collector *plan.Collector) *operator.Operator { solver.Region = filter.SelectOneRegion(solver.RandFollowerRegions(solver.TargetStoreID(), l.conf.Ranges), - nil, filter.NewRegionPendingFilter(), filter.NewRegionDownFilter()) + nil, filter.NewRegionPendingFilter(), filter.NewRegionDownFilter(), + filter.NewStoreRecentlySplitFilter(solver.GetStores())) if solver.Region == nil { log.Debug("store has no follower", zap.String("scheduler", l.GetName()), zap.Uint64("store-id", solver.TargetStoreID())) balanceLeaderNoFollowerRegionCounter.Inc() @@ -491,14 +491,6 @@ func (l *balanceLeaderScheduler) transferLeaderIn(solver *solver, collector *pla return nil } - if solver.Source.HasRecentlySplitRegions() { - log.Debug("source store recently splits region in one minutes", - zap.String("scheduler", l.GetName()), - zap.Uint64("store-id", leaderStoreID), - ) - balanceLeaderStoreRecentlySplitRegions.Inc() - return nil - } finalFilters := l.filters conf := solver.GetSchedulerConfig() if leaderFilter := filter.NewPlacementLeaderSafeguard(l.GetName(), conf, solver.GetBasicCluster(), solver.GetRuleManager(), solver.Region, solver.Source, false /*allowMoveLeader*/); leaderFilter != nil {