From e8c05e0e28e39e345b26f23de237879a90f9a752 Mon Sep 17 00:00:00 2001 From: okJiang <819421878@qq.com> Date: Thu, 25 Jul 2024 11:13:35 +0800 Subject: [PATCH] scheduler: Replace the input parameter of AddScheduler with types.CheckerSchedulerType. (#8416) ref tikv/pd#8379 1. Replace the input parameter of AddScheduler with types.CheckerSchedulerType. 2. Simplified the logic of AddScheduler by using a temporary map. 3. Remove scope's redundant definition and use types.CheckerSchedulerType. Signed-off-by: okJiang <819421878@qq.com> Co-authored-by: ti-chi-bot[bot] <108142056+ti-chi-bot[bot]@users.noreply.github.com> --- pkg/schedule/filter/counter.go | 60 ---------- pkg/schedule/filter/counter_test.go | 3 +- pkg/schedule/schedulers/balance_leader.go | 3 +- pkg/schedule/schedulers/balance_region.go | 3 +- pkg/schedule/schedulers/balance_witness.go | 3 +- pkg/schedule/type/type.go | 43 +++++++ server/api/scheduler.go | 127 ++++++--------------- server/handler.go | 118 +------------------ 8 files changed, 93 insertions(+), 267 deletions(-) diff --git a/pkg/schedule/filter/counter.go b/pkg/schedule/filter/counter.go index 29c75bbe41d..9742d2d0c9d 100644 --- a/pkg/schedule/filter/counter.go +++ b/pkg/schedule/filter/counter.go @@ -40,66 +40,6 @@ func (a action) String() string { return "unknown" } -type scope int - -const ( - // BalanceLeader is the filter type for balance leader. - BalanceLeader scope = iota - // BalanceRegion is the filter type for balance region. - BalanceRegion - // BalanceHotRegion is the filter type for hot region. - BalanceHotRegion - // BalanceWitness is the filter type for balance witness. - BalanceWitness - // Label is the filter type for replica. - Label - - // EvictLeader is the filter type for evict leader. - EvictLeader - // RegionScatter is the filter type for scatter region. - RegionScatter - // ReplicaChecker is the filter type for replica. - ReplicaChecker - // RuleChecker is the filter type for rule. - RuleChecker - - // GrantHotLeader is the filter type for grant hot leader. - GrantHotLeader - // ShuffleHotRegion is the filter type for shuffle hot region. - ShuffleHotRegion - // ShuffleRegion is the filter type for shuffle region. - ShuffleRegion - // RandomMerge is the filter type for random merge. - RandomMerge - scopeLen -) - -var scopes = [scopeLen]string{ - "balance-leader-scheduler", - "balance-region-scheduler", - "balance-hot-region-scheduler", - "balance-witness-scheduler", - "label-scheduler", - - "evict-leader-scheduler", - "region-scatter", - "replica-checker", - "rule-checker", - - "grant-hot-leader-scheduler", - "shuffle-region-scheduler", - "shuffle-region-scheduler", - "random-merge-scheduler", -} - -// String implements fmt.Stringer interface. -func (s scope) String() string { - if s >= scopeLen { - return "unknown" - } - return scopes[s] -} - type filterType int const ( diff --git a/pkg/schedule/filter/counter_test.go b/pkg/schedule/filter/counter_test.go index 78a1ef5395b..5b8d5144412 100644 --- a/pkg/schedule/filter/counter_test.go +++ b/pkg/schedule/filter/counter_test.go @@ -18,6 +18,7 @@ import ( "testing" "github.com/stretchr/testify/require" + types "github.com/tikv/pd/pkg/schedule/type" ) func TestString(t *testing.T) { @@ -39,7 +40,7 @@ func TestString(t *testing.T) { func TestCounter(t *testing.T) { re := require.New(t) - counter := NewCounter(BalanceLeader.String()) + counter := NewCounter(types.BalanceLeaderScheduler.String()) counter.inc(source, storeStateTombstone, 1, 2) counter.inc(target, storeStateTombstone, 1, 2) re.Equal(1, counter.counter[source][storeStateTombstone][1][2]) diff --git a/pkg/schedule/schedulers/balance_leader.go b/pkg/schedule/schedulers/balance_leader.go index 80755fbdbe5..899737536e2 100644 --- a/pkg/schedule/schedulers/balance_leader.go +++ b/pkg/schedule/schedulers/balance_leader.go @@ -31,6 +31,7 @@ import ( "github.com/tikv/pd/pkg/schedule/filter" "github.com/tikv/pd/pkg/schedule/operator" "github.com/tikv/pd/pkg/schedule/plan" + types "github.com/tikv/pd/pkg/schedule/type" "github.com/tikv/pd/pkg/storage/endpoint" "github.com/tikv/pd/pkg/utils/reflectutil" "github.com/tikv/pd/pkg/utils/syncutil" @@ -182,7 +183,7 @@ func newBalanceLeaderScheduler(opController *operator.Controller, conf *balanceL name: BalanceLeaderName, conf: conf, handler: newBalanceLeaderHandler(conf), - filterCounter: filter.NewCounter(filter.BalanceLeader.String()), + filterCounter: filter.NewCounter(types.BalanceLeaderScheduler.String()), } for _, option := range options { option(s) diff --git a/pkg/schedule/schedulers/balance_region.go b/pkg/schedule/schedulers/balance_region.go index 488b7635b77..b26830155b0 100644 --- a/pkg/schedule/schedulers/balance_region.go +++ b/pkg/schedule/schedulers/balance_region.go @@ -26,6 +26,7 @@ import ( "github.com/tikv/pd/pkg/schedule/filter" "github.com/tikv/pd/pkg/schedule/operator" "github.com/tikv/pd/pkg/schedule/plan" + types "github.com/tikv/pd/pkg/schedule/type" "go.uber.org/zap" ) @@ -58,7 +59,7 @@ func newBalanceRegionScheduler(opController *operator.Controller, conf *balanceR BaseScheduler: base, retryQuota: newRetryQuota(), conf: conf, - filterCounter: filter.NewCounter(filter.BalanceRegion.String()), + filterCounter: filter.NewCounter(types.BalanceRegionScheduler.String()), } for _, setOption := range opts { setOption(scheduler) diff --git a/pkg/schedule/schedulers/balance_witness.go b/pkg/schedule/schedulers/balance_witness.go index 0225d948815..1c4daa62634 100644 --- a/pkg/schedule/schedulers/balance_witness.go +++ b/pkg/schedule/schedulers/balance_witness.go @@ -32,6 +32,7 @@ import ( "github.com/tikv/pd/pkg/schedule/filter" "github.com/tikv/pd/pkg/schedule/operator" "github.com/tikv/pd/pkg/schedule/plan" + types "github.com/tikv/pd/pkg/schedule/type" "github.com/tikv/pd/pkg/storage/endpoint" "github.com/tikv/pd/pkg/utils/reflectutil" "github.com/tikv/pd/pkg/utils/syncutil" @@ -181,7 +182,7 @@ func newBalanceWitnessScheduler(opController *operator.Controller, conf *balance conf: conf, handler: newBalanceWitnessHandler(conf), counter: balanceWitnessCounter, - filterCounter: filter.NewCounter(filter.BalanceWitness.String()), + filterCounter: filter.NewCounter(types.BalanceWitnessScheduler.String()), } for _, option := range options { option(s) diff --git a/pkg/schedule/type/type.go b/pkg/schedule/type/type.go index 65b2f0f682d..26e1b6a737a 100644 --- a/pkg/schedule/type/type.go +++ b/pkg/schedule/type/type.go @@ -70,3 +70,46 @@ const ( // LabelScheduler is label scheduler name. LabelScheduler CheckerSchedulerType = "label-scheduler" ) + +// SchedulerTypeCompatibleMap temporarily exists for compatibility. +// TODO: remove it after all components use CheckerSchedulerType. +var SchedulerTypeCompatibleMap = map[CheckerSchedulerType]string{ + BalanceLeaderScheduler: "balance-leader", + BalanceRegionScheduler: "balance-region", + BalanceWitnessScheduler: "balance-witness", + EvictLeaderScheduler: "evict-leader", + EvictSlowStoreScheduler: "evict-slow-store", + EvictSlowTrendScheduler: "evict-slow-trend", + GrantLeaderScheduler: "grant-leader", + GrantHotRegionScheduler: "grant-hot-region", + HotRegionScheduler: "hot-region", + RandomMergeScheduler: "random-merge", + ScatterRangeScheduler: "scatter-range", + ShuffleHotRegionScheduler: "shuffle-hot-region", + ShuffleLeaderScheduler: "shuffle-leader", + ShuffleRegionScheduler: "shuffle-region", + SplitBucketScheduler: "split-bucket", + TransferWitnessLeaderScheduler: "transfer-witness-leader", + LabelScheduler: "label", +} + +var SchedulerStr2Type = map[string]CheckerSchedulerType{ + "balance-leader-scheduler": BalanceLeaderScheduler, + "balance-region-scheduler": BalanceRegionScheduler, + "balance-witness-scheduler": BalanceWitnessScheduler, + "evict-leader-scheduler": EvictLeaderScheduler, + "evict-slow-store-scheduler": EvictSlowStoreScheduler, + "evict-slow-trend-scheduler": EvictSlowTrendScheduler, + "grant-leader-scheduler": GrantLeaderScheduler, + "grant-hot-region-scheduler": GrantHotRegionScheduler, + "balance-hot-region-scheduler": HotRegionScheduler, + "random-merge-scheduler": RandomMergeScheduler, + // TODO: update to `scatter-range-scheduler` + "scatter-range": ScatterRangeScheduler, + "shuffle-hot-region-scheduler": ShuffleHotRegionScheduler, + "shuffle-leader-scheduler": ShuffleLeaderScheduler, + "shuffle-region-scheduler": ShuffleRegionScheduler, + "split-bucket-scheduler": SplitBucketScheduler, + "transfer-witness-leader-scheduler": TransferWitnessLeaderScheduler, + "label-scheduler": LabelScheduler, +} diff --git a/server/api/scheduler.go b/server/api/scheduler.go index b1d3e8c07af..e8b9b54380c 100644 --- a/server/api/scheduler.go +++ b/server/api/scheduler.go @@ -17,15 +17,19 @@ package api import ( "net/http" "net/url" + "strconv" "strings" "github.com/gorilla/mux" "github.com/pingcap/errors" + "github.com/pingcap/log" "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/pkg/schedule/schedulers" + types "github.com/tikv/pd/pkg/schedule/type" "github.com/tikv/pd/pkg/utils/apiutil" "github.com/tikv/pd/server" "github.com/unrolled/render" + "go.uber.org/zap" ) type schedulerHandler struct { @@ -81,48 +85,18 @@ func (h *schedulerHandler) CreateScheduler(w http.ResponseWriter, r *http.Reques return } - switch name { - case schedulers.BalanceLeaderName: - if err := h.AddBalanceLeaderScheduler(); err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - case schedulers.BalanceWitnessName: - if err := h.AddBalanceWitnessScheduler(); err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - case schedulers.TransferWitnessLeaderName: - if err := h.AddTransferWitnessLeaderScheduler(); err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - case schedulers.HotRegionName: - if err := h.AddBalanceHotRegionScheduler(); err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - case schedulers.EvictSlowTrendName: - if err := h.AddEvictSlowTrendScheduler(); err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - case schedulers.BalanceRegionName: - if err := h.AddBalanceRegionScheduler(); err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - case schedulers.LabelName: - if err := h.AddLabelScheduler(); err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - case schedulers.ScatterRangeName: - var args []string + tp, ok := types.SchedulerStr2Type[name] + if !ok { + h.r.JSON(w, http.StatusBadRequest, "unknown scheduler") + return + } + var args []string + collector := func(v string) { + args = append(args, v) + } - collector := func(v string) { - args = append(args, v) - } + switch tp { + case types.ScatterRangeScheduler: if err := apiutil.CollectEscapeStringOption("start_key", input, collector); err != nil { h.r.JSON(w, http.StatusInternalServerError, err.Error()) return @@ -137,64 +111,39 @@ func (h *schedulerHandler) CreateScheduler(w http.ResponseWriter, r *http.Reques h.r.JSON(w, http.StatusInternalServerError, err.Error()) return } - if err := h.AddScatterRangeScheduler(args...); err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - - case schedulers.GrantLeaderName, schedulers.EvictLeaderName: + case types.GrantLeaderScheduler, types.EvictLeaderScheduler: storeID, ok := input["store_id"].(float64) if !ok { h.r.JSON(w, http.StatusBadRequest, "missing store id") return } - exist, err := h.AddEvictOrGrant(storeID, name) - if err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - // we should ensure whether it is the first time to create evict-leader-scheduler - // or just update the evict-leader. - if exist { + var ( + exist bool + err error + ) + if exist, err = h.IsSchedulerExisted(name); exist { + if err := h.RedirectSchedulerUpdate(name, storeID); err != nil { + h.r.JSON(w, http.StatusInternalServerError, err.Error()) + return + } + log.Info("update scheduler", zap.String("scheduler-name", name), zap.Uint64("store-id", uint64(storeID))) h.r.JSON(w, http.StatusOK, "The scheduler has been applied to the store.") return } - case schedulers.ShuffleLeaderName: - if err := h.AddShuffleLeaderScheduler(); err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - case schedulers.ShuffleRegionName: - if err := h.AddShuffleRegionScheduler(); err != nil { + if err != nil && !errors.ErrorEqual(err, errs.ErrSchedulerNotFound.FastGenByArgs()) { h.r.JSON(w, http.StatusInternalServerError, err.Error()) return } - case schedulers.RandomMergeName: - if err := h.AddRandomMergeScheduler(); err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - case schedulers.ShuffleHotRegionName: + + collector(strconv.FormatUint(uint64(storeID), 10)) + case types.ShuffleHotRegionScheduler: limit := uint64(1) l, ok := input["limit"].(float64) if ok { limit = uint64(l) } - if err := h.AddShuffleHotRegionScheduler(limit); err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - case schedulers.EvictSlowStoreName: - if err := h.AddEvictSlowStoreScheduler(); err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - case schedulers.SplitBucketName: - if err := h.AddSplitBucketScheduler(); err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - case schedulers.GrantHotRegionName: + collector(strconv.FormatUint(limit, 10)) + case types.GrantHotRegionScheduler: leaderID, ok := input["store-leader-id"].(string) if !ok { h.r.JSON(w, http.StatusBadRequest, "missing leader id") @@ -205,12 +154,12 @@ func (h *schedulerHandler) CreateScheduler(w http.ResponseWriter, r *http.Reques h.r.JSON(w, http.StatusBadRequest, "missing store id") return } - if err := h.AddGrantHotRegionScheduler(leaderID, peerIDs); err != nil { - h.r.JSON(w, http.StatusInternalServerError, err.Error()) - return - } - default: - h.r.JSON(w, http.StatusBadRequest, "unknown scheduler") + collector(leaderID) + collector(peerIDs) + } + + if err := h.AddScheduler(tp, args...); err != nil { + h.r.JSON(w, http.StatusInternalServerError, err.Error()) return } diff --git a/server/handler.go b/server/handler.go index adcd429ee34..cc924cf9a0b 100644 --- a/server/handler.go +++ b/server/handler.go @@ -20,10 +20,8 @@ import ( "net/url" "path" "path/filepath" - "strconv" "time" - "github.com/pingcap/errors" "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/log" "github.com/tikv/pd/pkg/core" @@ -36,6 +34,7 @@ import ( sche "github.com/tikv/pd/pkg/schedule/core" "github.com/tikv/pd/pkg/schedule/handler" "github.com/tikv/pd/pkg/schedule/schedulers" + types "github.com/tikv/pd/pkg/schedule/type" "github.com/tikv/pd/pkg/statistics" "github.com/tikv/pd/pkg/statistics/utils" "github.com/tikv/pd/pkg/storage" @@ -186,7 +185,8 @@ func (h *Handler) GetAllRequestHistoryHotRegion(request *HistoryHotRegionsReques } // AddScheduler adds a scheduler. -func (h *Handler) AddScheduler(name string, args ...string) error { +func (h *Handler) AddScheduler(tp types.CheckerSchedulerType, args ...string) error { + name := types.SchedulerTypeCompatibleMap[tp] c, err := h.GetRaftCluster() if err != nil { return err @@ -246,91 +246,6 @@ func (h *Handler) RemoveScheduler(name string) error { return err } -// AddBalanceLeaderScheduler adds a balance-leader-scheduler. -func (h *Handler) AddBalanceLeaderScheduler() error { - return h.AddScheduler(schedulers.BalanceLeaderType) -} - -// AddBalanceWitnessScheduler adds a balance-witness-scheduler. -func (h *Handler) AddBalanceWitnessScheduler() error { - return h.AddScheduler(schedulers.BalanceWitnessType) -} - -// AddTransferWitnessLeaderScheduler adds a transfer-witness-leader-scheduler. -func (h *Handler) AddTransferWitnessLeaderScheduler() error { - return h.AddScheduler(schedulers.TransferWitnessLeaderType) -} - -// AddBalanceRegionScheduler adds a balance-region-scheduler. -func (h *Handler) AddBalanceRegionScheduler() error { - return h.AddScheduler(schedulers.BalanceRegionType) -} - -// AddBalanceHotRegionScheduler adds a balance-hot-region-scheduler. -func (h *Handler) AddBalanceHotRegionScheduler() error { - return h.AddScheduler(schedulers.HotRegionType) -} - -// AddEvictSlowTrendScheduler adds a evict-slow-trend-scheduler. -func (h *Handler) AddEvictSlowTrendScheduler() error { - return h.AddScheduler(schedulers.EvictSlowTrendType) -} - -// AddLabelScheduler adds a label-scheduler. -func (h *Handler) AddLabelScheduler() error { - return h.AddScheduler(schedulers.LabelType) -} - -// AddScatterRangeScheduler adds a balance-range-leader-scheduler -func (h *Handler) AddScatterRangeScheduler(args ...string) error { - return h.AddScheduler(schedulers.ScatterRangeType, args...) -} - -// AddGrantLeaderScheduler adds a grant-leader-scheduler. -func (h *Handler) AddGrantLeaderScheduler(storeID uint64) error { - return h.AddScheduler(schedulers.GrantLeaderType, strconv.FormatUint(storeID, 10)) -} - -// AddEvictLeaderScheduler adds an evict-leader-scheduler. -func (h *Handler) AddEvictLeaderScheduler(storeID uint64) error { - return h.AddScheduler(schedulers.EvictLeaderType, strconv.FormatUint(storeID, 10)) -} - -// AddShuffleLeaderScheduler adds a shuffle-leader-scheduler. -func (h *Handler) AddShuffleLeaderScheduler() error { - return h.AddScheduler(schedulers.ShuffleLeaderType) -} - -// AddShuffleRegionScheduler adds a shuffle-region-scheduler. -func (h *Handler) AddShuffleRegionScheduler() error { - return h.AddScheduler(schedulers.ShuffleRegionType) -} - -// AddShuffleHotRegionScheduler adds a shuffle-hot-region-scheduler. -func (h *Handler) AddShuffleHotRegionScheduler(limit uint64) error { - return h.AddScheduler(schedulers.ShuffleHotRegionType, strconv.FormatUint(limit, 10)) -} - -// AddEvictSlowStoreScheduler adds a evict-slow-store-scheduler. -func (h *Handler) AddEvictSlowStoreScheduler() error { - return h.AddScheduler(schedulers.EvictSlowStoreType) -} - -// AddSplitBucketScheduler adds a split-bucket-scheduler. -func (h *Handler) AddSplitBucketScheduler() error { - return h.AddScheduler(schedulers.SplitBucketType) -} - -// AddRandomMergeScheduler adds a random-merge-scheduler. -func (h *Handler) AddRandomMergeScheduler() error { - return h.AddScheduler(schedulers.RandomMergeType) -} - -// AddGrantHotRegionScheduler adds a grant-hot-region-scheduler -func (h *Handler) AddGrantHotRegionScheduler(leaderID, peers string) error { - return h.AddScheduler(schedulers.GrantHotRegionType, leaderID, peers) -} - // SetAllStoresLimit is used to set limit of all stores. func (h *Handler) SetAllStoresLimit(ratePerMin float64, limitType storelimit.Type) error { c, err := h.GetRaftCluster() @@ -557,7 +472,7 @@ func (h *Handler) GetHistoryHotRegionIter( } // RedirectSchedulerUpdate update scheduler config. Export this func to help handle damaged store. -func (h *Handler) redirectSchedulerUpdate(name string, storeID float64) error { +func (h *Handler) RedirectSchedulerUpdate(name string, storeID float64) error { input := make(map[string]any) input["name"] = name input["store_id"] = storeID @@ -571,28 +486,3 @@ func (h *Handler) redirectSchedulerUpdate(name string, storeID float64) error { } return apiutil.PostJSONIgnoreResp(h.s.GetHTTPClient(), updateURL, body) } - -// AddEvictOrGrant add evict leader scheduler or grant leader scheduler. -func (h *Handler) AddEvictOrGrant(storeID float64, name string) (exist bool, err error) { - if exist, err = h.IsSchedulerExisted(name); !exist { - if err != nil && !errors.ErrorEqual(err, errs.ErrSchedulerNotFound.FastGenByArgs()) { - return exist, err - } - switch name { - case schedulers.EvictLeaderName: - err = h.AddEvictLeaderScheduler(uint64(storeID)) - case schedulers.GrantLeaderName: - err = h.AddGrantLeaderScheduler(uint64(storeID)) - } - if err != nil { - return exist, err - } - } else { - if err := h.redirectSchedulerUpdate(name, storeID); err != nil { - return exist, err - } - log.Info("update scheduler", zap.String("scheduler-name", name), zap.Uint64("store-id", uint64(storeID))) - return exist, nil - } - return exist, nil -}