From e2df10e5ace9b4434280b4d521eef27ca6552c6d Mon Sep 17 00:00:00 2001 From: ZenoTan Date: Mon, 13 Jul 2020 12:18:44 +0800 Subject: [PATCH 1/7] Use label for store limit instead of tiflash only --- server/cluster/cluster.go | 27 +++++++++++++++++++++++---- server/config/config.go | 11 ++++++++++- server/config/persist_options.go | 26 ++++++++++++++++++++++++++ server/core/store.go | 4 +--- server/grpc_service.go | 2 +- server/handler.go | 19 +++++++++++++++++++ server/server.go | 2 +- 7 files changed, 81 insertions(+), 10 deletions(-) diff --git a/server/cluster/cluster.go b/server/cluster/cluster.go index a7f7d9117dd..65bd334dcc9 100644 --- a/server/cluster/cluster.go +++ b/server/cluster/cluster.go @@ -1681,6 +1681,11 @@ func (c *RaftCluster) GetStoreLimitByType(storeID uint64, typ storelimit.Type) f return c.opt.GetStoreLimitByType(storeID, typ) } +// GetAllStoresLimit returns all store limit +func (c *RaftCluster) GetLabelStoresLimit(label config.StoreLabel) map[config.StoreLabel]config.StoreLimitConfig { + return c.opt.GetLabelStoresLimit(label) +} + // GetAllStoresLimit returns all store limit func (c *RaftCluster) GetAllStoresLimit() map[uint64]config.StoreLimitConfig { return c.opt.GetAllStoresLimit() @@ -1693,12 +1698,21 @@ func (c *RaftCluster) AddStoreLimit(store *metapb.Store) { AddPeer: config.DefaultStoreLimit.GetDefaultStoreLimit(storelimit.AddPeer), RemovePeer: config.DefaultStoreLimit.GetDefaultStoreLimit(storelimit.RemovePeer), } - if core.IsTiFlashStore(store) { - sc = config.StoreLimitConfig{ - AddPeer: config.DefaultTiFlashStoreLimit.GetDefaultStoreLimit(storelimit.AddPeer), - RemovePeer: config.DefaultTiFlashStoreLimit.GetDefaultStoreLimit(storelimit.RemovePeer), + for _, l := range store.GetLabels() { + label := config.StoreLabel{Key: l.GetKey(), Value: l.GetValue()} + if limit, ok := config.OtherStoreLimits[label]; ok { + sc = config.StoreLimitConfig{ + AddPeer: limit.GetDefaultStoreLimit(storelimit.AddPeer), + RemovePeer: limit.GetDefaultStoreLimit(storelimit.RemovePeer), + } } } + //if core.IsTiFlashStore(store) { + // sc = config.StoreLimitConfig{ + // AddPeer: config.DefaultTiFlashStoreLimit.GetDefaultStoreLimit(storelimit.AddPeer), + // RemovePeer: config.DefaultTiFlashStoreLimit.GetDefaultStoreLimit(storelimit.RemovePeer), + // } + //} storeID := store.GetId() cfg.StoreLimit[storeID] = sc c.opt.SetScheduleConfig(cfg) @@ -1719,6 +1733,11 @@ func (c *RaftCluster) SetStoreLimit(storeID uint64, typ storelimit.Type, ratePer c.opt.SetStoreLimit(storeID, typ, ratePerMin) } +// SetAllStoresLimit sets all store limit for a given type and rate. +func (c *RaftCluster) SetLabelStoresLimit(label config.StoreLabel, typ storelimit.Type, ratePerMin float64) { + c.opt.SetLabelStoresLimit(label, typ, ratePerMin) +} + // SetAllStoresLimit sets all store limit for a given type and rate. func (c *RaftCluster) SetAllStoresLimit(typ storelimit.Type, ratePerMin float64) { c.opt.SetAllStoresLimit(typ, ratePerMin) diff --git a/server/config/config.go b/server/config/config.go index c61ecfaa3b6..6521f1fcd8e 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -221,7 +221,10 @@ var ( // DefaultStoreLimit is the default store limit of add peer and remove peer. DefaultStoreLimit StoreLimit = StoreLimit{AddPeer: 15, RemovePeer: 15} // DefaultTiFlashStoreLimit is the default TiFlash store limit of add peer and remove peer. - DefaultTiFlashStoreLimit StoreLimit = StoreLimit{AddPeer: 30, RemovePeer: 30} + //DefaultTiFlashStoreLimit StoreLimit = StoreLimit{AddPeer: 30, RemovePeer: 30} + OtherStoreLimits = map[StoreLabel]StoreLimit{ + StoreLabel{Key: "engine", Value: "tiflash"}: {AddPeer: 30, RemovePeer: 30}, + } ) // StoreLimit is the default limit of adding peer and removing peer when putting stores. @@ -583,6 +586,7 @@ type ScheduleConfig struct { StoreBalanceRate float64 `toml:"store-balance-rate" json:"store-balance-rate,omitempty"` // StoreLimit is the limit of scheduling for stores. StoreLimit map[uint64]StoreLimitConfig `toml:"store-limit" json:"store-limit"` + StoreLabelLimit map[StoreLabel]StoreLimitConfig `toml:"store-label-limit" json:"store-label-limit"` // TolerantSizeRatio is the ratio of buffer size for balance scheduler. TolerantSizeRatio float64 `toml:"tolerant-size-ratio" json:"tolerant-size-ratio"` // @@ -659,6 +663,10 @@ func (c *ScheduleConfig) Clone() *ScheduleConfig { for k, v := range c.StoreLimit { storeLimit[k] = v } + storeLabelLimit := make(map[StoreLabel]StoreLimitConfig, len(c.StoreLabelLimit)) + for k, v := range c.StoreLabelLimit { + storeLabelLimit[k] = v + } return &ScheduleConfig{ MaxSnapshotCount: c.MaxSnapshotCount, MaxPendingPeerCount: c.MaxPendingPeerCount, @@ -677,6 +685,7 @@ func (c *ScheduleConfig) Clone() *ScheduleConfig { HotRegionScheduleLimit: c.HotRegionScheduleLimit, HotRegionCacheHitsThreshold: c.HotRegionCacheHitsThreshold, StoreLimit: storeLimit, + StoreLabelLimit: storeLabelLimit, TolerantSizeRatio: c.TolerantSizeRatio, LowSpaceRatio: c.LowSpaceRatio, HighSpaceRatio: c.HighSpaceRatio, diff --git a/server/config/persist_options.go b/server/config/persist_options.go index 45315b7b345..2df452c2027 100644 --- a/server/config/persist_options.go +++ b/server/config/persist_options.go @@ -202,6 +202,27 @@ func (o *PersistOptions) SetStoreLimit(storeID uint64, typ storelimit.Type, rate o.SetScheduleConfig(v) } +// SetAllStoresLimit sets all store limit for a given type and rate. +func (o *PersistOptions) SetLabelStoresLimit(label StoreLabel, typ storelimit.Type, ratePerMin float64) { + v := o.GetScheduleConfig().Clone() + switch typ { + case storelimit.AddPeer: + DefaultStoreLimit.SetDefaultStoreLimit(storelimit.AddPeer, ratePerMin) + for storeID := range v.StoreLimit { + sc := StoreLimitConfig{AddPeer: ratePerMin, RemovePeer: v.StoreLimit[storeID].RemovePeer} + v.StoreLimit[storeID] = sc + } + case storelimit.RemovePeer: + DefaultStoreLimit.SetDefaultStoreLimit(storelimit.RemovePeer, ratePerMin) + for storeID := range v.StoreLimit { + sc := StoreLimitConfig{AddPeer: v.StoreLimit[storeID].AddPeer, RemovePeer: ratePerMin} + v.StoreLimit[storeID] = sc + } + } + + o.SetScheduleConfig(v) +} + // SetAllStoresLimit sets all store limit for a given type and rate. func (o *PersistOptions) SetAllStoresLimit(typ storelimit.Type, ratePerMin float64) { v := o.GetScheduleConfig().Clone() @@ -296,6 +317,11 @@ func (o *PersistOptions) GetStoreLimitByType(storeID uint64, typ storelimit.Type } } +// GetAllStoresLimit returns the limit of all stores. +func (o *PersistOptions) GetLabelStoresLimit(label StoreLabel) map[StoreLabel]StoreLimitConfig { + return o.GetScheduleConfig().StoreLabelLimit +} + // GetAllStoresLimit returns the limit of all stores. func (o *PersistOptions) GetAllStoresLimit() map[uint64]StoreLimitConfig { return o.GetScheduleConfig().StoreLimit diff --git a/server/core/store.go b/server/core/store.go index 429be4ee3bb..461988a3142 100644 --- a/server/core/store.go +++ b/server/core/store.go @@ -673,9 +673,7 @@ func (s *StoresInfo) UpdateStoreStatus(storeID uint64, leaderCount int, regionCo } } -// IsTiFlashStore used to judge flash store. -// FIXME: remove the hack way -func IsTiFlashStore(store *metapb.Store) bool { +func IsPlacementNeeded(store *metapb.Store) bool { for _, l := range store.GetLabels() { if l.GetKey() == "engine" && l.GetValue() == "tiflash" { return true diff --git a/server/grpc_service.go b/server/grpc_service.go index cb98b45c8cf..3b9c79e4739 100644 --- a/server/grpc_service.go +++ b/server/grpc_service.go @@ -224,7 +224,7 @@ func (s *Server) PutStore(ctx context.Context, request *pdpb.PutStoreRequest) (* } // NOTE: can be removed when placement rules feature is enabled by default. - if !s.GetConfig().Replication.EnablePlacementRules && core.IsTiFlashStore(store) { + if !s.GetConfig().Replication.EnablePlacementRules && core.IsPlacementNeeded(store) { return nil, status.Errorf(codes.FailedPrecondition, "placement rules is disabled") } diff --git a/server/handler.go b/server/handler.go index 4ef1be83266..d257023c054 100644 --- a/server/handler.go +++ b/server/handler.go @@ -417,6 +417,16 @@ func (h *Handler) GetHistory(start time.Time) ([]operator.OpHistory, error) { return c.GetHistory(start), nil } +// SetAllStoresLimit is used to set limit of all stores. +func (h *Handler) SetLabelStoresLimit(label config.StoreLabel, ratePerMin float64, limitType storelimit.Type) error { + c, err := h.GetRaftCluster() + if err != nil { + return err + } + c.SetLabelStoresLimit(label, limitType, ratePerMin) + return nil +} + // SetAllStoresLimit is used to set limit of all stores. func (h *Handler) SetAllStoresLimit(ratePerMin float64, limitType storelimit.Type) error { c, err := h.GetRaftCluster() @@ -427,6 +437,15 @@ func (h *Handler) SetAllStoresLimit(ratePerMin float64, limitType storelimit.Typ return nil } +// GetAllStoresLimit is used to get limit of all stores. +func (h *Handler) GetLabelStoresLimit(label config.StoreLabel, limitType storelimit.Type) (map[config.StoreLabel]config.StoreLimitConfig, error) { + c, err := h.GetRaftCluster() + if err != nil { + return nil, err + } + return c.GetLabelStoresLimit(label), nil +} + // GetAllStoresLimit is used to get limit of all stores. func (h *Handler) GetAllStoresLimit(limitType storelimit.Type) (map[uint64]config.StoreLimitConfig, error) { c, err := h.GetRaftCluster() diff --git a/server/server.go b/server/server.go index 30b4ea0284e..4ecdf32dbc2 100644 --- a/server/server.go +++ b/server/server.go @@ -775,7 +775,7 @@ func (s *Server) SetReplicationConfig(cfg config.ReplicationConfig) error { } else { // NOTE: can be removed after placement rules feature is enabled by default. for _, s := range raftCluster.GetStores() { - if !s.IsTombstone() && core.IsTiFlashStore(s.GetMeta()) { + if !s.IsTombstone() && core.IsPlacementNeeded(s.GetMeta()) { return errors.New("cannot disable placement rules with TiFlash nodes") } } From ba478c608af6fc456a638f1f7a56da987d478825 Mon Sep 17 00:00:00 2001 From: ZenoTan Date: Mon, 13 Jul 2020 13:19:50 +0800 Subject: [PATCH 2/7] Add some comments --- server/cluster/cluster.go | 10 ++-------- server/config/config.go | 4 ++-- server/config/persist_options.go | 4 ++-- server/core/store.go | 1 + server/handler.go | 2 +- 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/server/cluster/cluster.go b/server/cluster/cluster.go index 65bd334dcc9..0b4b43cbe8d 100644 --- a/server/cluster/cluster.go +++ b/server/cluster/cluster.go @@ -1681,7 +1681,7 @@ func (c *RaftCluster) GetStoreLimitByType(storeID uint64, typ storelimit.Type) f return c.opt.GetStoreLimitByType(storeID, typ) } -// GetAllStoresLimit returns all store limit +// GetLabelStoresLimit returns store limit for a label. func (c *RaftCluster) GetLabelStoresLimit(label config.StoreLabel) map[config.StoreLabel]config.StoreLimitConfig { return c.opt.GetLabelStoresLimit(label) } @@ -1707,12 +1707,6 @@ func (c *RaftCluster) AddStoreLimit(store *metapb.Store) { } } } - //if core.IsTiFlashStore(store) { - // sc = config.StoreLimitConfig{ - // AddPeer: config.DefaultTiFlashStoreLimit.GetDefaultStoreLimit(storelimit.AddPeer), - // RemovePeer: config.DefaultTiFlashStoreLimit.GetDefaultStoreLimit(storelimit.RemovePeer), - // } - //} storeID := store.GetId() cfg.StoreLimit[storeID] = sc c.opt.SetScheduleConfig(cfg) @@ -1733,7 +1727,7 @@ func (c *RaftCluster) SetStoreLimit(storeID uint64, typ storelimit.Type, ratePer c.opt.SetStoreLimit(storeID, typ, ratePerMin) } -// SetAllStoresLimit sets all store limit for a given type and rate. +// SetLabelStoresLimit sets store limit for a given label, type and rate. func (c *RaftCluster) SetLabelStoresLimit(label config.StoreLabel, typ storelimit.Type, ratePerMin float64) { c.opt.SetLabelStoresLimit(label, typ, ratePerMin) } diff --git a/server/config/config.go b/server/config/config.go index 6521f1fcd8e..23e28829a31 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -220,8 +220,7 @@ var ( defaultLocationLabels = []string{} // DefaultStoreLimit is the default store limit of add peer and remove peer. DefaultStoreLimit StoreLimit = StoreLimit{AddPeer: 15, RemovePeer: 15} - // DefaultTiFlashStoreLimit is the default TiFlash store limit of add peer and remove peer. - //DefaultTiFlashStoreLimit StoreLimit = StoreLimit{AddPeer: 30, RemovePeer: 30} + // OtherStoreLimits are other store limits of add peer and remove peer. OtherStoreLimits = map[StoreLabel]StoreLimit{ StoreLabel{Key: "engine", Value: "tiflash"}: {AddPeer: 30, RemovePeer: 30}, } @@ -586,6 +585,7 @@ type ScheduleConfig struct { StoreBalanceRate float64 `toml:"store-balance-rate" json:"store-balance-rate,omitempty"` // StoreLimit is the limit of scheduling for stores. StoreLimit map[uint64]StoreLimitConfig `toml:"store-limit" json:"store-limit"` + // StoreLabelLimit is the limit of scheduling for stores by labels. StoreLabelLimit map[StoreLabel]StoreLimitConfig `toml:"store-label-limit" json:"store-label-limit"` // TolerantSizeRatio is the ratio of buffer size for balance scheduler. TolerantSizeRatio float64 `toml:"tolerant-size-ratio" json:"tolerant-size-ratio"` diff --git a/server/config/persist_options.go b/server/config/persist_options.go index 2df452c2027..612c97c1fc7 100644 --- a/server/config/persist_options.go +++ b/server/config/persist_options.go @@ -202,7 +202,7 @@ func (o *PersistOptions) SetStoreLimit(storeID uint64, typ storelimit.Type, rate o.SetScheduleConfig(v) } -// SetAllStoresLimit sets all store limit for a given type and rate. +// SetLabelStoresLimit sets store limit for a given label, type and rate. func (o *PersistOptions) SetLabelStoresLimit(label StoreLabel, typ storelimit.Type, ratePerMin float64) { v := o.GetScheduleConfig().Clone() switch typ { @@ -317,7 +317,7 @@ func (o *PersistOptions) GetStoreLimitByType(storeID uint64, typ storelimit.Type } } -// GetAllStoresLimit returns the limit of all stores. +// GetLabelStoresLimit returns the limit of stores for a label. func (o *PersistOptions) GetLabelStoresLimit(label StoreLabel) map[StoreLabel]StoreLimitConfig { return o.GetScheduleConfig().StoreLabelLimit } diff --git a/server/core/store.go b/server/core/store.go index 461988a3142..f261d9e5d6c 100644 --- a/server/core/store.go +++ b/server/core/store.go @@ -673,6 +673,7 @@ func (s *StoresInfo) UpdateStoreStatus(storeID uint64, leaderCount int, regionCo } } +// Judge if it needs placement rule. func IsPlacementNeeded(store *metapb.Store) bool { for _, l := range store.GetLabels() { if l.GetKey() == "engine" && l.GetValue() == "tiflash" { diff --git a/server/handler.go b/server/handler.go index d257023c054..b9a495c05aa 100644 --- a/server/handler.go +++ b/server/handler.go @@ -417,7 +417,7 @@ func (h *Handler) GetHistory(start time.Time) ([]operator.OpHistory, error) { return c.GetHistory(start), nil } -// SetAllStoresLimit is used to set limit of all stores. +// SetLabelStoresLimit is used to set limit of stores for a label. func (h *Handler) SetLabelStoresLimit(label config.StoreLabel, ratePerMin float64, limitType storelimit.Type) error { c, err := h.GetRaftCluster() if err != nil { From 367255c3b526c7e7b2b65702873a4d4594ecd03f Mon Sep 17 00:00:00 2001 From: ZenoTan Date: Tue, 21 Jul 2020 16:49:51 +0800 Subject: [PATCH 3/7] Better implementation --- server/cluster/cluster.go | 4 ++-- server/config/config.go | 6 +++--- server/config/persist_options.go | 24 ++++++++++++------------ server/handler.go | 4 ++-- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/server/cluster/cluster.go b/server/cluster/cluster.go index 708b8bdcc1e..e9f33254d38 100644 --- a/server/cluster/cluster.go +++ b/server/cluster/cluster.go @@ -1696,7 +1696,7 @@ func (c *RaftCluster) GetStoreLimitByType(storeID uint64, typ storelimit.Type) f } // GetLabelStoresLimit returns store limit for a label. -func (c *RaftCluster) GetLabelStoresLimit(label config.StoreLabel) map[config.StoreLabel]config.StoreLimitConfig { +func (c *RaftCluster) GetLabelStoresLimit(label config.StoreLabel) config.StoreLimitConfig { return c.opt.GetLabelStoresLimit(label) } @@ -1714,7 +1714,7 @@ func (c *RaftCluster) AddStoreLimit(store *metapb.Store) { } for _, l := range store.GetLabels() { label := config.StoreLabel{Key: l.GetKey(), Value: l.GetValue()} - if limit, ok := config.OtherStoreLimits[label]; ok { + if limit, ok := config.StoreLabelLimits[label]; ok { sc = config.StoreLimitConfig{ AddPeer: limit.GetDefaultStoreLimit(storelimit.AddPeer), RemovePeer: limit.GetDefaultStoreLimit(storelimit.RemovePeer), diff --git a/server/config/config.go b/server/config/config.go index f3f14be474e..109b981fb0d 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -221,9 +221,9 @@ var ( defaultRuntimeServices = []string{} defaultLocationLabels = []string{} // DefaultStoreLimit is the default store limit of add peer and remove peer. - DefaultStoreLimit StoreLimit = StoreLimit{AddPeer: 15, RemovePeer: 15} - // OtherStoreLimits are other store limits of add peer and remove peer. - OtherStoreLimits = map[StoreLabel]StoreLimit{ + DefaultStoreLimit = StoreLimit{AddPeer: 15, RemovePeer: 15} + // StoreLabelLimits are other store limits of add peer and remove peer. + StoreLabelLimits = map[StoreLabel]*StoreLimit{ StoreLabel{Key: "engine", Value: "tiflash"}: {AddPeer: 30, RemovePeer: 30}, } ) diff --git a/server/config/persist_options.go b/server/config/persist_options.go index 612c97c1fc7..1234770dfef 100644 --- a/server/config/persist_options.go +++ b/server/config/persist_options.go @@ -205,19 +205,15 @@ func (o *PersistOptions) SetStoreLimit(storeID uint64, typ storelimit.Type, rate // SetLabelStoresLimit sets store limit for a given label, type and rate. func (o *PersistOptions) SetLabelStoresLimit(label StoreLabel, typ storelimit.Type, ratePerMin float64) { v := o.GetScheduleConfig().Clone() + if _, ok := StoreLabelLimits[label]; !ok { + sl := DefaultStoreLimit + StoreLabelLimits[label] = &sl + } switch typ { case storelimit.AddPeer: - DefaultStoreLimit.SetDefaultStoreLimit(storelimit.AddPeer, ratePerMin) - for storeID := range v.StoreLimit { - sc := StoreLimitConfig{AddPeer: ratePerMin, RemovePeer: v.StoreLimit[storeID].RemovePeer} - v.StoreLimit[storeID] = sc - } + StoreLabelLimits[label].SetDefaultStoreLimit(storelimit.AddPeer, ratePerMin) case storelimit.RemovePeer: - DefaultStoreLimit.SetDefaultStoreLimit(storelimit.RemovePeer, ratePerMin) - for storeID := range v.StoreLimit { - sc := StoreLimitConfig{AddPeer: v.StoreLimit[storeID].AddPeer, RemovePeer: ratePerMin} - v.StoreLimit[storeID] = sc - } + StoreLabelLimits[label].SetDefaultStoreLimit(storelimit.RemovePeer, ratePerMin) } o.SetScheduleConfig(v) @@ -318,8 +314,12 @@ func (o *PersistOptions) GetStoreLimitByType(storeID uint64, typ storelimit.Type } // GetLabelStoresLimit returns the limit of stores for a label. -func (o *PersistOptions) GetLabelStoresLimit(label StoreLabel) map[StoreLabel]StoreLimitConfig { - return o.GetScheduleConfig().StoreLabelLimit +func (o *PersistOptions) GetLabelStoresLimit(label StoreLabel) StoreLimitConfig { + if l, ok := o.GetScheduleConfig().StoreLabelLimit[label]; !ok { + return l + } else { + return StoreLimitConfig{AddPeer: DefaultStoreLimit.AddPeer, RemovePeer: DefaultStoreLimit.RemovePeer} + } } // GetAllStoresLimit returns the limit of all stores. diff --git a/server/handler.go b/server/handler.go index cf02ff73a7d..15609061510 100644 --- a/server/handler.go +++ b/server/handler.go @@ -430,10 +430,10 @@ func (h *Handler) SetAllStoresLimit(ratePerMin float64, limitType storelimit.Typ } // GetAllStoresLimit is used to get limit of all stores. -func (h *Handler) GetLabelStoresLimit(label config.StoreLabel, limitType storelimit.Type) (map[config.StoreLabel]config.StoreLimitConfig, error) { +func (h *Handler) GetLabelStoresLimit(label config.StoreLabel, limitType storelimit.Type) (config.StoreLimitConfig, error) { c, err := h.GetRaftCluster() if err != nil { - return nil, err + return config.StoreLimitConfig{AddPeer: config.DefaultStoreLimit.AddPeer, RemovePeer: config.DefaultStoreLimit.RemovePeer}, err } return c.GetLabelStoresLimit(label), nil } From 8f44e51563078a16fb17a22697e45ee8006dac32 Mon Sep 17 00:00:00 2001 From: ZenoTan Date: Tue, 21 Jul 2020 17:36:57 +0800 Subject: [PATCH 4/7] Update existing limits --- server/cluster/cluster.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/server/cluster/cluster.go b/server/cluster/cluster.go index e9f33254d38..f71ef7140ef 100644 --- a/server/cluster/cluster.go +++ b/server/cluster/cluster.go @@ -1695,6 +1695,16 @@ func (c *RaftCluster) GetStoreLimitByType(storeID uint64, typ storelimit.Type) f return c.opt.GetStoreLimitByType(storeID, typ) } +func (c *RaftCluster) GetLabelStores(label config.StoreLabel) []uint64 { + var stores []uint64 + for _, s := range c.GetStores() { + if s.GetLabelValue(label.Key) == label.Value { + stores = append(stores, s.GetID()) + } + } + return stores +} + // GetLabelStoresLimit returns store limit for a label. func (c *RaftCluster) GetLabelStoresLimit(label config.StoreLabel) config.StoreLimitConfig { return c.opt.GetLabelStoresLimit(label) @@ -1743,6 +1753,10 @@ func (c *RaftCluster) SetStoreLimit(storeID uint64, typ storelimit.Type, ratePer // SetLabelStoresLimit sets store limit for a given label, type and rate. func (c *RaftCluster) SetLabelStoresLimit(label config.StoreLabel, typ storelimit.Type, ratePerMin float64) { + stores := c.GetLabelStores(label) + for _, s := range stores { + c.SetStoreLimit(s, typ, ratePerMin) + } c.opt.SetLabelStoresLimit(label, typ, ratePerMin) } From c58edd97c2de298f09c1ef7c45f8552592ce1713 Mon Sep 17 00:00:00 2001 From: ZenoTan Date: Wed, 22 Jul 2020 11:02:53 +0800 Subject: [PATCH 5/7] Update store api --- server/api/store.go | 56 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/server/api/store.go b/server/api/store.go index 319fd92d60d..93a6b949a09 100644 --- a/server/api/store.go +++ b/server/api/store.go @@ -434,6 +434,19 @@ func (h *storesHandler) SetAllLimit(w http.ResponseWriter, r *http.Request) { return } + label := config.StoreLabel{} + labelKey, keyOk := input["labelKey"] + labelValue, valueOk := input["labelValue"] + if keyOk && valueOk { + label.Key = labelKey.(string) + label.Value = labelValue.(string) + } else if !keyOk && !valueOk { + + } else { + h.rd.JSON(w, http.StatusBadRequest, "label key and value must match") + return + } + rateVal, ok := input["rate"] if !ok { h.rd.JSON(w, http.StatusBadRequest, "rate unset") @@ -452,9 +465,16 @@ func (h *storesHandler) SetAllLimit(w http.ResponseWriter, r *http.Request) { } for _, typ := range typeValues { - if err := h.SetAllStoresLimit(ratePerMin, typ); err != nil { - h.rd.JSON(w, http.StatusInternalServerError, err.Error()) - return + if label.Key == "" { + if err := h.SetLabelStoresLimit(label, ratePerMin, typ); err != nil { + h.rd.JSON(w, http.StatusInternalServerError, err.Error()) + return + } + } else { + if err := h.SetAllStoresLimit(ratePerMin, typ); err != nil { + h.rd.JSON(w, http.StatusInternalServerError, err.Error()) + return + } } } @@ -469,8 +489,34 @@ func (h *storesHandler) SetAllLimit(w http.ResponseWriter, r *http.Request) { // @Failure 500 {string} string "PD server failed to proceed the request." // @Router /stores/limit [get] func (h *storesHandler) GetAllLimit(w http.ResponseWriter, r *http.Request) { - limits := h.GetScheduleConfig().StoreLimit - h.rd.JSON(w, http.StatusOK, limits) + var input map[string]interface{} + if err := apiutil.ReadJSONRespondError(h.rd, w, r.Body, &input); err != nil { + return + } + + label := config.StoreLabel{} + labelKey, keyOk := input["labelKey"] + labelValue, valueOk := input["labelValue"] + if keyOk && valueOk { + label.Key = labelKey.(string) + label.Value = labelValue.(string) + } else if !keyOk && !valueOk { + + } else { + h.rd.JSON(w, http.StatusBadRequest, "label key and value must match") + return + } + + if keyOk { + if limit, err := h.GetLabelStoresLimit(label, 0); err != nil { + return + } else { + h.rd.JSON(w, http.StatusOK, limit) + } + } else { + limits := h.GetScheduleConfig().StoreLimit + h.rd.JSON(w, http.StatusOK, limits) + } } // @Tags store From b57d74b3889e30bfc35dbc3aaf55f68813ba86b2 Mon Sep 17 00:00:00 2001 From: ZenoTan Date: Wed, 22 Jul 2020 14:40:01 +0800 Subject: [PATCH 6/7] Update store command --- tools/pd-ctl/pdctl/command/store_command.go | 26 +++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/tools/pd-ctl/pdctl/command/store_command.go b/tools/pd-ctl/pdctl/command/store_command.go index 148287cc7f7..1a71edad577 100644 --- a/tools/pd-ctl/pdctl/command/store_command.go +++ b/tools/pd-ctl/pdctl/command/store_command.go @@ -89,9 +89,9 @@ func NewSetStoreWeightCommand() *cobra.Command { // NewStoreLimitCommand returns a limit subcommand of storeCmd. func NewStoreLimitCommand() *cobra.Command { c := &cobra.Command{ - Use: "limit []|[| ]", + Use: "limit []|[| ]|[