diff --git a/pkg/mock/mockcluster/config.go b/pkg/mock/mockcluster/config.go index 9535b0e5ab6..166cc9f4fe8 100644 --- a/pkg/mock/mockcluster/config.go +++ b/pkg/mock/mockcluster/config.go @@ -80,6 +80,11 @@ func (mc *Cluster) SetTolerantSizeRatio(v float64) { mc.updateScheduleConfig(func(s *config.ScheduleConfig) { s.TolerantSizeRatio = v }) } +// SetRegionScoreFormulaVersion updates the RegionScoreFormulaVersion configuration. +func (mc *Cluster) SetRegionScoreFormulaVersion(v string) { + mc.updateScheduleConfig(func(s *config.ScheduleConfig) { s.RegionScoreFormulaVersion = v }) +} + // SetLeaderScheduleLimit updates the LeaderScheduleLimit configuration. func (mc *Cluster) SetLeaderScheduleLimit(v int) { mc.updateScheduleConfig(func(s *config.ScheduleConfig) { s.LeaderScheduleLimit = uint64(v) }) diff --git a/server/api/config.go b/server/api/config.go index 5c5f13c33c4..654b44facbc 100644 --- a/server/api/config.go +++ b/server/api/config.go @@ -63,7 +63,7 @@ func (h *confHandler) Get(w http.ResponseWriter, r *http.Request) { // @Router /config/default [get] func (h *confHandler) GetDefault(w http.ResponseWriter, r *http.Request) { config := config.NewConfig() - err := config.Adjust(nil) + err := config.Adjust(nil, false) if err != nil { h.rd.JSON(w, http.StatusInternalServerError, err.Error()) } diff --git a/server/api/store.go b/server/api/store.go index 08beae85357..a176f194f33 100644 --- a/server/api/store.go +++ b/server/api/store.go @@ -89,7 +89,7 @@ func newStoreInfo(opt *config.ScheduleConfig, store *core.StoreInfo) *StoreInfo LeaderSize: store.GetLeaderSize(), RegionCount: store.GetRegionCount(), RegionWeight: store.GetRegionWeight(), - RegionScore: store.RegionScore(opt.HighSpaceRatio, opt.LowSpaceRatio, 0), + RegionScore: store.RegionScore(opt.RegionScoreFormulaVersion, opt.HighSpaceRatio, opt.LowSpaceRatio, 0, 0), RegionSize: store.GetRegionSize(), SendingSnapCount: store.GetSendingSnapCount(), ReceivingSnapCount: store.GetReceivingSnapCount(), diff --git a/server/cluster/cluster_test.go b/server/cluster/cluster_test.go index e2f4c1c53a1..55aef87d30d 100644 --- a/server/cluster/cluster_test.go +++ b/server/cluster/cluster_test.go @@ -768,7 +768,7 @@ type testCluster struct { func newTestScheduleConfig() (*config.ScheduleConfig, *config.PersistOptions, error) { cfg := config.NewConfig() cfg.Schedule.TolerantSizeRatio = 5 - if err := cfg.Adjust(nil); err != nil { + if err := cfg.Adjust(nil, false); err != nil { return nil, nil, err } opt := config.NewPersistOptions(cfg) diff --git a/server/config/config.go b/server/config/config.go index 79f3b5e14c6..43d666bbd28 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -389,7 +389,7 @@ func (c *Config) Parse(arguments []string) error { return errors.Errorf("'%s' is an invalid flag", c.flagSet.Arg(0)) } - err = c.Adjust(meta) + err = c.Adjust(meta, false) return err } @@ -461,7 +461,7 @@ func (m *configMetaData) CheckUndecoded() error { } // Adjust is used to adjust the PD configurations. -func (c *Config) Adjust(meta *toml.MetaData) error { +func (c *Config) Adjust(meta *toml.MetaData, reloading bool) error { configMetaData := newConfigMetadata(meta) if err := configMetaData.CheckUndecoded(); err != nil { c.WarningMsgs = append(c.WarningMsgs, err.Error()) @@ -538,7 +538,7 @@ func (c *Config) Adjust(meta *toml.MetaData) error { adjustString(&c.Metric.PushJob, c.Name) - if err := c.Schedule.adjust(configMetaData.Child("schedule")); err != nil { + if err := c.Schedule.adjust(configMetaData.Child("schedule"), reloading); err != nil { return err } if err := c.Replication.adjust(configMetaData.Child("replication")); err != nil { @@ -654,6 +654,8 @@ type ScheduleConfig struct { // HighSpaceRatio is the highest usage ratio of store which regraded as high space. // High space means there is a lot of spare capacity, and store region score varies directly with used size. HighSpaceRatio float64 `toml:"high-space-ratio" json:"high-space-ratio"` + // RegionScoreFormulaVersion is used to control the formula used to calculate region score. + RegionScoreFormulaVersion string `toml:"region-score-formula-version" json:"region-score-formula-version"` // SchedulerMaxWaitingOperator is the max coexist operators for each scheduler. SchedulerMaxWaitingOperator uint64 `toml:"scheduler-max-waiting-operator" json:"scheduler-max-waiting-operator"` // WARN: DisableLearner is deprecated. @@ -728,22 +730,23 @@ func (c *ScheduleConfig) Clone() *ScheduleConfig { } const ( - defaultMaxReplicas = 3 - defaultMaxSnapshotCount = 3 - defaultMaxPendingPeerCount = 16 - defaultMaxMergeRegionSize = 20 - defaultMaxMergeRegionKeys = 200000 - defaultSplitMergeInterval = 1 * time.Hour - defaultPatrolRegionInterval = 100 * time.Millisecond - defaultMaxStoreDownTime = 30 * time.Minute - defaultLeaderScheduleLimit = 4 - defaultRegionScheduleLimit = 2048 - defaultReplicaScheduleLimit = 64 - defaultMergeScheduleLimit = 8 - defaultHotRegionScheduleLimit = 4 - defaultTolerantSizeRatio = 0 - defaultLowSpaceRatio = 0.8 - defaultHighSpaceRatio = 0.7 + defaultMaxReplicas = 3 + defaultMaxSnapshotCount = 3 + defaultMaxPendingPeerCount = 16 + defaultMaxMergeRegionSize = 20 + defaultMaxMergeRegionKeys = 200000 + defaultSplitMergeInterval = 1 * time.Hour + defaultPatrolRegionInterval = 100 * time.Millisecond + defaultMaxStoreDownTime = 30 * time.Minute + defaultLeaderScheduleLimit = 4 + defaultRegionScheduleLimit = 2048 + defaultReplicaScheduleLimit = 64 + defaultMergeScheduleLimit = 8 + defaultHotRegionScheduleLimit = 4 + defaultTolerantSizeRatio = 0 + defaultLowSpaceRatio = 0.8 + defaultHighSpaceRatio = 0.7 + defaultRegionScoreFormulaVersion = "v2" // defaultHotRegionCacheHitsThreshold is the low hit number threshold of the // hot region. defaultHotRegionCacheHitsThreshold = 3 @@ -754,7 +757,7 @@ const ( defaultEnableCrossTableMerge = true ) -func (c *ScheduleConfig) adjust(meta *configMetaData) error { +func (c *ScheduleConfig) adjust(meta *configMetaData, reloading bool) error { if !meta.IsDefined("max-snapshot-count") { adjustUint64(&c.MaxSnapshotCount, defaultMaxSnapshotCount) } @@ -809,6 +812,11 @@ func (c *ScheduleConfig) adjust(meta *configMetaData) error { adjustFloat64(&c.LowSpaceRatio, defaultLowSpaceRatio) adjustFloat64(&c.HighSpaceRatio, defaultHighSpaceRatio) + // new cluster:v2, old cluster:v1 + if !meta.IsDefined("region-score-formula-version") && !reloading { + adjustString(&c.RegionScoreFormulaVersion, defaultRegionScoreFormulaVersion) + } + adjustSchedulers(&c.Schedulers, DefaultSchedulers) for k, b := range c.migrateConfigurationMap() { diff --git a/server/config/config_test.go b/server/config/config_test.go index b695d4cf6f8..be4fc887f00 100644 --- a/server/config/config_test.go +++ b/server/config/config_test.go @@ -59,7 +59,7 @@ func (s *testConfigSuite) TestTLS(c *C) { func (s *testConfigSuite) TestBadFormatJoinAddr(c *C) { cfg := NewConfig() cfg.Join = "127.0.0.1:2379" // Wrong join addr without scheme. - c.Assert(cfg.Adjust(nil), NotNil) + c.Assert(cfg.Adjust(nil, false), NotNil) } func (s *testConfigSuite) TestReloadConfig(c *C) { @@ -114,9 +114,29 @@ func (s *testConfigSuite) TestReloadUpgrade(c *C) { c.Assert(newOpt.GetPDServerConfig().KeyType, Equals, defaultKeyType) // should be set to default value. } +func (s *testConfigSuite) TestReloadUpgrade2(c *C) { + opt, err := newTestScheduleOption() + c.Assert(err, IsNil) + + // Simulate an old configuration that does not contain ScheduleConfig. + type OldConfig struct { + Replication ReplicationConfig `toml:"replication" json:"replication"` + } + old := &OldConfig{ + Replication: *opt.GetReplicationConfig(), + } + storage := core.NewStorage(kv.NewMemoryKV()) + c.Assert(storage.SaveConfig(old), IsNil) + + newOpt, err := newTestScheduleOption() + c.Assert(err, IsNil) + c.Assert(newOpt.Reload(storage), IsNil) + c.Assert(newOpt.GetScheduleConfig().RegionScoreFormulaVersion, Equals, "") // formulaVersion keep old value when reloading. +} + func (s *testConfigSuite) TestValidation(c *C) { cfg := NewConfig() - c.Assert(cfg.Adjust(nil), IsNil) + c.Assert(cfg.Adjust(nil, false), IsNil) cfg.Log.File.Filename = path.Join(cfg.DataDir, "test") c.Assert(cfg.Validate(), NotNil) @@ -154,7 +174,7 @@ leader-schedule-limit = 0 cfg := NewConfig() meta, err := toml.Decode(cfgData, &cfg) c.Assert(err, IsNil) - err = cfg.Adjust(&meta) + err = cfg.Adjust(&meta, false) c.Assert(err, IsNil) // When invalid, use default values. @@ -185,7 +205,7 @@ type = "random-merge" cfg = NewConfig() meta, err = toml.Decode(cfgData, &cfg) c.Assert(err, IsNil) - err = cfg.Adjust(&meta) + err = cfg.Adjust(&meta, false) c.Assert(err, IsNil) c.Assert(strings.Contains(cfg.WarningMsgs[0], "Config contains undefined item"), IsTrue) @@ -200,7 +220,7 @@ type = "random-merge-schedulers" cfg = NewConfig() meta, err = toml.Decode(cfgData, &cfg) c.Assert(err, IsNil) - err = cfg.Adjust(&meta) + err = cfg.Adjust(&meta, false) c.Assert(err, NotNil) // Check correct schedulers name @@ -214,7 +234,7 @@ type = "random-merge" cfg = NewConfig() meta, err = toml.Decode(cfgData, &cfg) c.Assert(err, IsNil) - err = cfg.Adjust(&meta) + err = cfg.Adjust(&meta, false) c.Assert(err, IsNil) cfgData = ` @@ -225,7 +245,7 @@ address = "localhost:9090" cfg = NewConfig() meta, err = toml.Decode(cfgData, &cfg) c.Assert(err, IsNil) - err = cfg.Adjust(&meta) + err = cfg.Adjust(&meta, false) c.Assert(err, IsNil) c.Assert(cfg.Metric.PushInterval.Duration, Equals, 35*time.Second) @@ -238,7 +258,7 @@ tso-update-physical-interval = "10ms" cfg = NewConfig() meta, err = toml.Decode(cfgData, &cfg) c.Assert(err, IsNil) - err = cfg.Adjust(&meta) + err = cfg.Adjust(&meta, false) c.Assert(err, IsNil) c.Assert(cfg.TSOUpdatePhysicalInterval.Duration, Equals, minTSOUpdatePhysicalInterval) @@ -249,7 +269,7 @@ tso-update-physical-interval = "15s" cfg = NewConfig() meta, err = toml.Decode(cfgData, &cfg) c.Assert(err, IsNil) - err = cfg.Adjust(&meta) + err = cfg.Adjust(&meta, false) c.Assert(err, IsNil) c.Assert(cfg.TSOUpdatePhysicalInterval.Duration, Equals, maxTSOUpdatePhysicalInterval) @@ -260,7 +280,7 @@ func (s *testConfigSuite) TestMigrateFlags(c *C) { cfg := NewConfig() meta, err := toml.Decode(s, &cfg) c.Assert(err, IsNil) - err = cfg.Adjust(&meta) + err = cfg.Adjust(&meta, false) return cfg, err } cfg, err := load(` @@ -290,7 +310,7 @@ disable-make-up-replica = false func newTestScheduleOption() (*PersistOptions, error) { cfg := NewConfig() - if err := cfg.Adjust(nil); err != nil { + if err := cfg.Adjust(nil, false); err != nil { return nil, err } opt := NewPersistOptions(cfg) @@ -354,7 +374,7 @@ dashboard-address = "foo" cfg := NewConfig() meta, err := toml.Decode(t.cfgData, &cfg) c.Assert(err, IsNil) - err = cfg.Adjust(&meta) + err = cfg.Adjust(&meta, false) c.Assert(err != nil, Equals, t.hasErr) if !t.hasErr { c.Assert(cfg.PDServerCfg.DashboardAddress, Equals, t.dashboardAddress) @@ -372,7 +392,7 @@ tidb-cert-path = "/path/client.pem" cfg := NewConfig() meta, err := toml.Decode(cfgData, &cfg) c.Assert(err, IsNil) - err = cfg.Adjust(&meta) + err = cfg.Adjust(&meta, false) c.Assert(err, IsNil) c.Assert(cfg.Dashboard.TiDBCAPath, Equals, "/path/ca.pem") c.Assert(cfg.Dashboard.TiDBKeyPath, Equals, "/path/client-key.pem") @@ -393,7 +413,7 @@ tidb-cert-path = "/path/client.pem" cfg = NewConfig() meta, err = toml.Decode(cfgData, &cfg) c.Assert(err, IsNil) - err = cfg.Adjust(&meta) + err = cfg.Adjust(&meta, false) c.Assert(err, IsNil) c.Assert(cfg.Dashboard.EnableTelemetry, Equals, test.EnableTelemetry) } @@ -415,7 +435,7 @@ wait-store-timeout = "120s" cfg := NewConfig() meta, err := toml.Decode(cfgData, &cfg) c.Assert(err, IsNil) - err = cfg.Adjust(&meta) + err = cfg.Adjust(&meta, false) c.Assert(err, IsNil) c.Assert(cfg.ReplicationMode.ReplicationMode, Equals, "dr-auto-sync") @@ -430,20 +450,20 @@ wait-store-timeout = "120s" cfg = NewConfig() meta, err = toml.Decode("", &cfg) c.Assert(err, IsNil) - err = cfg.Adjust(&meta) + err = cfg.Adjust(&meta, false) c.Assert(err, IsNil) c.Assert(cfg.ReplicationMode.ReplicationMode, Equals, "majority") } func (s *testConfigSuite) TestConfigClone(c *C) { cfg := &Config{} - cfg.Adjust(nil) + cfg.Adjust(nil, false) c.Assert(cfg.Clone(), DeepEquals, cfg) emptyConfigMetaData := newConfigMetadata(nil) schedule := &ScheduleConfig{} - schedule.adjust(emptyConfigMetaData) + schedule.adjust(emptyConfigMetaData, false) c.Assert(schedule.Clone(), DeepEquals, schedule) replication := &ReplicationConfig{} diff --git a/server/config/persist_options.go b/server/config/persist_options.go index 0c532ab08b6..aa23cd9338f 100644 --- a/server/config/persist_options.go +++ b/server/config/persist_options.go @@ -413,6 +413,11 @@ func (o *PersistOptions) GetHighSpaceRatio() float64 { return o.GetScheduleConfig().HighSpaceRatio } +// GetRegionScoreFormulaVersion returns the formula version config. +func (o *PersistOptions) GetRegionScoreFormulaVersion() string { + return o.GetScheduleConfig().RegionScoreFormulaVersion +} + // GetSchedulerMaxWaitingOperator returns the number of the max waiting operators. func (o *PersistOptions) GetSchedulerMaxWaitingOperator() uint64 { return o.getTTLUintOr(schedulerMaxWaitingOperatorKey, o.GetScheduleConfig().SchedulerMaxWaitingOperator) @@ -563,7 +568,7 @@ func (o *PersistOptions) Persist(storage *core.Storage) error { func (o *PersistOptions) Reload(storage *core.Storage) error { cfg := &Config{} // pass nil to initialize cfg to default values (all items undefined) - cfg.Adjust(nil) + cfg.Adjust(nil, true) isExist, err := storage.LoadConfig(cfg) if err != nil { diff --git a/server/config/util.go b/server/config/util.go index 8df92262f51..da3efb5b5b1 100644 --- a/server/config/util.go +++ b/server/config/util.go @@ -83,6 +83,6 @@ func NewTestOptions() *PersistOptions { RegisterScheduler(d.Type) } c := NewConfig() - c.Adjust(nil) + c.Adjust(nil, false) return NewPersistOptions(c) } diff --git a/server/core/store.go b/server/core/store.go index 959f524502c..00f3d7214a9 100644 --- a/server/core/store.go +++ b/server/core/store.go @@ -30,6 +30,7 @@ const ( // Interval to save store meta (including heartbeat ts) to etcd. storePersistInterval = 5 * time.Minute mb = 1 << 20 // megabyte + gb = 1 << 30 ) // StoreInfo contains information about a store. @@ -234,7 +235,21 @@ func (s *StoreInfo) LeaderScore(policy SchedulePolicy, delta int64) float64 { } // RegionScore returns the store's region score. -func (s *StoreInfo) RegionScore(highSpaceRatio, lowSpaceRatio float64, delta int64) float64 { +// Deviation It is used to control the direction of the deviation considered +// when calculating the region score. It is set to -1 when it is the source +// store of balance, 1 when it is the target, and 0 in the rest of cases. +func (s *StoreInfo) RegionScore(version string, highSpaceRatio, lowSpaceRatio float64, delta int64, deviation int) float64 { + switch version { + case "v2": + return s.regionScoreV2(delta, deviation) + case "v1": + fallthrough + default: + return s.regionScoreV1(highSpaceRatio, lowSpaceRatio, delta) + } +} + +func (s *StoreInfo) regionScoreV1(highSpaceRatio, lowSpaceRatio float64, delta int64) float64 { var score float64 var amplification float64 available := float64(s.GetAvailable()) / mb @@ -279,6 +294,29 @@ func (s *StoreInfo) RegionScore(highSpaceRatio, lowSpaceRatio float64, delta int return score / math.Max(s.GetRegionWeight(), minWeight) } +func (s *StoreInfo) regionScoreV2(delta int64, deviation int) float64 { + A := float64(float64(s.GetAvgAvailable())-float64(deviation)*float64(s.GetAvailableDeviation())) / gb + C := float64(s.GetCapacity()) / gb + R := float64(s.GetRegionSize() + delta) + var ( + K, M float64 = 1, 256 // Experience value to control the weight of the available influence on score + F float64 = 20 // Experience value to prevent some nodes from running out of disk space prematurely. + ) + + var score float64 + if A >= C || C < 1 { + score = R + } else if A > F { + // As the amount of data increases (available becomes smaller), the weight of region size on total score + // increases. Ideally, all nodes converge at the position where remaining space is F (default 20GiB). + score = (K + M*(math.Log(C)-math.Log(A-F+1))/(C-A+F-1)) * R + } else { + // When remaining space is less then F, the score is mainly determined by available space. + score = (K+M*math.Log(C)/C)*R + (F-A)*(K+M*math.Log(F)/F) + } + return score / math.Max(s.GetRegionWeight(), minWeight) +} + // StorageSize returns store's used storage size reported from tikv. func (s *StoreInfo) StorageSize() uint64 { return s.GetUsedSize() @@ -321,18 +359,6 @@ func (s *StoreInfo) ResourceSize(kind ResourceKind) int64 { } } -// ResourceScore returns score of leader/region in the store. -func (s *StoreInfo) ResourceScore(scheduleKind ScheduleKind, highSpaceRatio, lowSpaceRatio float64, delta int64) float64 { - switch scheduleKind.Resource { - case LeaderKind: - return s.LeaderScore(scheduleKind.Policy, delta) - case RegionKind: - return s.RegionScore(highSpaceRatio, lowSpaceRatio, delta) - default: - return 0 - } -} - // ResourceWeight returns weight of leader/region in the score func (s *StoreInfo) ResourceWeight(kind ResourceKind) float64 { switch kind { diff --git a/server/core/store_test.go b/server/core/store_test.go index c216853d98e..bfcf23b7e84 100644 --- a/server/core/store_test.go +++ b/server/core/store_test.go @@ -110,7 +110,7 @@ func (s *testStoreSuite) TestRegionScore(c *C) { SetStoreStats(stats), SetRegionSize(1), ) - score := store.RegionScore(0.7, 0.9, 0) + score := store.RegionScore("v1", 0.7, 0.9, 0, 0) // Region score should never be NaN, or /store API would fail. c.Assert(math.IsNaN(score), Equals, false) } diff --git a/server/schedule/filter/comparer.go b/server/schedule/filter/comparer.go index ec894aa846a..1f85b8bed7f 100644 --- a/server/schedule/filter/comparer.go +++ b/server/schedule/filter/comparer.go @@ -26,8 +26,8 @@ type StoreComparer func(a, b *core.StoreInfo) int // score. func RegionScoreComparer(opt *config.PersistOptions) StoreComparer { return func(a, b *core.StoreInfo) int { - sa := a.RegionScore(opt.GetHighSpaceRatio(), opt.GetLowSpaceRatio(), 0) - sb := b.RegionScore(opt.GetHighSpaceRatio(), opt.GetLowSpaceRatio(), 0) + sa := a.RegionScore(opt.GetRegionScoreFormulaVersion(), opt.GetHighSpaceRatio(), opt.GetLowSpaceRatio(), 0, 0) + sb := b.RegionScore(opt.GetRegionScoreFormulaVersion(), opt.GetHighSpaceRatio(), opt.GetLowSpaceRatio(), 0, 0) switch { case sa > sb: return 1 diff --git a/server/schedulers/balance_region.go b/server/schedulers/balance_region.go index 6ed5a99f2d4..bfb73ef7f2f 100644 --- a/server/schedulers/balance_region.go +++ b/server/schedulers/balance_region.go @@ -139,8 +139,8 @@ func (s *balanceRegionScheduler) Schedule(cluster opt.Cluster) []*operator.Opera sort.Slice(stores, func(i, j int) bool { iOp := opInfluence.GetStoreInfluence(stores[i].GetID()).ResourceProperty(kind) jOp := opInfluence.GetStoreInfluence(stores[j].GetID()).ResourceProperty(kind) - return stores[i].RegionScore(opts.GetHighSpaceRatio(), opts.GetLowSpaceRatio(), iOp) > - stores[j].RegionScore(opts.GetHighSpaceRatio(), opts.GetLowSpaceRatio(), jOp) + return stores[i].RegionScore(opts.GetRegionScoreFormulaVersion(), opts.GetHighSpaceRatio(), opts.GetLowSpaceRatio(), iOp, -1) > + stores[j].RegionScore(opts.GetRegionScoreFormulaVersion(), opts.GetHighSpaceRatio(), opts.GetLowSpaceRatio(), jOp, -1) }) for _, source := range stores { sourceID := source.GetID() diff --git a/server/schedulers/balance_test.go b/server/schedulers/balance_test.go index e539ac915a6..407eb658e1c 100644 --- a/server/schedulers/balance_test.go +++ b/server/schedulers/balance_test.go @@ -101,6 +101,7 @@ func (s *testBalanceSuite) TestShouldBalance(c *C) { opt := config.NewTestOptions() tc := mockcluster.NewCluster(opt) tc.SetTolerantSizeRatio(2.5) + tc.SetRegionScoreFormulaVersion("v1") ctx, cancel := context.WithCancel(context.Background()) defer cancel() oc := schedule.NewOperatorController(ctx, nil, nil) @@ -749,6 +750,7 @@ func (s *testBalanceRegionSchedulerSuite) TestBalance1(c *C) { tc.DisableFeature(versioninfo.JointConsensus) tc.SetTolerantSizeRatio(1) tc.SetRegionScheduleLimit(1) + tc.SetRegionScoreFormulaVersion("v1") oc := schedule.NewOperatorController(s.ctx, nil, nil) source := core.NewRegionInfo( diff --git a/server/schedulers/utils.go b/server/schedulers/utils.go index 6cc1160330c..878bb3c28c2 100644 --- a/server/schedulers/utils.go +++ b/server/schedulers/utils.go @@ -45,9 +45,16 @@ func shouldBalance(cluster opt.Cluster, source, target *core.StoreInfo, region * tolerantResource := getTolerantResource(cluster, region, kind) sourceInfluence := opInfluence.GetStoreInfluence(sourceID).ResourceProperty(kind) targetInfluence := opInfluence.GetStoreInfluence(targetID).ResourceProperty(kind) + sourceDelta, targetDelta := sourceInfluence-tolerantResource, targetInfluence+tolerantResource opts := cluster.GetOpts() - sourceScore = source.ResourceScore(kind, opts.GetHighSpaceRatio(), opts.GetLowSpaceRatio(), sourceInfluence-tolerantResource) - targetScore = target.ResourceScore(kind, opts.GetHighSpaceRatio(), opts.GetLowSpaceRatio(), targetInfluence+tolerantResource) + switch kind.Resource { + case core.LeaderKind: + sourceScore = source.LeaderScore(kind.Policy, sourceDelta) + targetScore = target.LeaderScore(kind.Policy, targetDelta) + case core.RegionKind: + sourceScore = source.RegionScore(opts.GetRegionScoreFormulaVersion(), opts.GetHighSpaceRatio(), opts.GetLowSpaceRatio(), sourceDelta, -1) + targetScore = target.RegionScore(opts.GetRegionScoreFormulaVersion(), opts.GetHighSpaceRatio(), opts.GetLowSpaceRatio(), targetDelta, 1) + } if opts.IsDebugMetricsEnabled() { opInfluenceStatus.WithLabelValues(scheduleName, strconv.FormatUint(sourceID, 10), "source").Set(float64(sourceInfluence)) opInfluenceStatus.WithLabelValues(scheduleName, strconv.FormatUint(targetID, 10), "target").Set(float64(targetInfluence)) diff --git a/server/statistics/store_collection.go b/server/statistics/store_collection.go index d5cb35fdc4e..60d6bdb3f3c 100644 --- a/server/statistics/store_collection.go +++ b/server/statistics/store_collection.go @@ -93,7 +93,7 @@ func (s *storeStatistics) Observe(store *core.StoreInfo, stats *StoresStats) { s.RegionCount += store.GetRegionCount() s.LeaderCount += store.GetLeaderCount() - storeStatusGauge.WithLabelValues(storeAddress, id, "region_score").Set(store.RegionScore(s.opt.GetHighSpaceRatio(), s.opt.GetLowSpaceRatio(), 0)) + storeStatusGauge.WithLabelValues(storeAddress, id, "region_score").Set(store.RegionScore(s.opt.GetRegionScoreFormulaVersion(), s.opt.GetHighSpaceRatio(), s.opt.GetLowSpaceRatio(), 0, 0)) storeStatusGauge.WithLabelValues(storeAddress, id, "leader_score").Set(store.LeaderScore(s.opt.GetLeaderSchedulePolicy(), 0)) storeStatusGauge.WithLabelValues(storeAddress, id, "region_size").Set(float64(store.GetRegionSize())) storeStatusGauge.WithLabelValues(storeAddress, id, "region_count").Set(float64(store.GetRegionCount())) diff --git a/server/testutil.go b/server/testutil.go index 545f409e86d..d7d8766b7fd 100644 --- a/server/testutil.go +++ b/server/testutil.go @@ -88,7 +88,7 @@ func NewTestSingleConfig(c *check.C) *config.Config { log.ReplaceGlobals(cfg.GetZapLogger(), cfg.GetZapLogProperties()) }) - c.Assert(cfg.Adjust(nil), check.IsNil) + c.Assert(cfg.Adjust(nil, false), check.IsNil) return cfg } diff --git a/tests/server/cluster/cluster_test.go b/tests/server/cluster/cluster_test.go index 0af8d349d20..6421bb34a8b 100644 --- a/tests/server/cluster/cluster_test.go +++ b/tests/server/cluster/cluster_test.go @@ -574,7 +574,7 @@ func (s *clusterTestSuite) TestSetScheduleOpt(c *C) { cfg := config.NewConfig() cfg.Schedule.TolerantSizeRatio = 5 - err = cfg.Adjust(nil) + err = cfg.Adjust(nil, false) c.Assert(err, IsNil) opt := config.NewPersistOptions(cfg) c.Assert(err, IsNil) diff --git a/tools/pd-simulator/simulator/config.go b/tools/pd-simulator/simulator/config.go index b1e76f923b8..737c0021671 100644 --- a/tools/pd-simulator/simulator/config.go +++ b/tools/pd-simulator/simulator/config.go @@ -94,5 +94,5 @@ func (sc *SimConfig) Adjust(meta *toml.MetaData) error { adjustDuration(&sc.ServerConfig.ElectionInterval, defaultElectionInterval) adjustDuration(&sc.ServerConfig.LeaderPriorityCheckInterval, defaultLeaderPriorityCheckInterval) - return sc.ServerConfig.Adjust(meta) + return sc.ServerConfig.Adjust(meta, false) }