Skip to content

Commit 2443eee

Browse files
committed
allocator: add BaseScorerOptionsNoConvergence
This commit disables range-count based rebalancing in the replicate queue if CountBasedRebalanceDisabled is true. Currently, when selecting a rebalance target, the allocator constructs an equivalence class for each existing replica. This class includes all stores that are not worse than the existing replica in terms of constraint conformance, diversity score, and disk fullness. At this stage, range count convergence is not yet considered. The allocator then evaluates each candidate set using `ScorerOptions`, which populates candidates' attributes such as balance score, convergence score, and range count with respect to the equivalence class, and determines the best candidate within each equivalence class. To disable range count–based rebalancing, this commit introduces a new scorer option, `BaseScorerOptionsNoConvergence`. This scorer assigns the same score to all stores, effectively treating candidates within the same equivalence class the same. It is only used when both MMA and `DisableCountBasedRebalancingIfMMAEnabled` are enabled. Note that this new scorer option is applied only in `ReplicaPlanner.considerRebalance` and `ReplicaPlanner.ShouldPlanChange`. As a result, range-count based rebalancing is disabled during rebalancing, but range count is still considered when allocator adds new replicas (such as `AllocateVoter`), choosing a rebalance target in the old store rebalancer (`StoreRebalancer.applyRangeRebalance`), and when removing replicas (`Allocator.RemoveVoter`).
1 parent 7e040eb commit 2443eee

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

pkg/kv/kvserver/allocator/allocatorimpl/allocator.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,6 +2065,18 @@ func (a *Allocator) ScorerOptions(ctx context.Context) *RangeCountScorerOptions
20652065
}
20662066
}
20672067

2068+
// BaseScorerOptionsWithNoConvergence returns the base scorer options with no
2069+
// convergence heuristics.
2070+
func (a *Allocator) BaseScorerOptionsWithNoConvergence() BaseScorerOptionsNoConvergence {
2071+
return BaseScorerOptionsNoConvergence{
2072+
BaseScorerOptions: BaseScorerOptions{
2073+
IOOverload: a.IOOverloadOptions(),
2074+
DiskCapacity: a.DiskOptions(),
2075+
Deterministic: a.deterministic,
2076+
},
2077+
}
2078+
}
2079+
20682080
// ScorerOptionsForScatter returns the scorer options for scattering purposes.
20692081
func (a *Allocator) ScorerOptionsForScatter(ctx context.Context) *ScatterScorerOptions {
20702082
return &ScatterScorerOptions{

pkg/kv/kvserver/allocator/allocatorimpl/allocator_scorer.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,69 @@ func (bo BaseScorerOptions) adjustRangeCountForScoring(rangeCount int) int {
401401
return rangeCount
402402
}
403403

404+
// BaseScorerOptionsNoConvergence is the base scorer options that does not
405+
// involve any heuristics or convergence scoring.
406+
//
407+
// It assigns the same score to all stores, effectively treating candidates
408+
// within the same equivalence class the same and disabling range-count based
409+
// convergence rebalancing.
410+
//
411+
// Note that this new scorer option is applied used in
412+
// ReplicaPlanner.considerRebalance and ReplicaPlanner.ShouldPlanChange. As a
413+
// result, range-count based rebalancing is disabled during rebalancing, but
414+
// range count is still considered when allocator adds new replicas (such as
415+
// AllocateVoter), choosing a rebalance target in the old store rebalancer
416+
// (StoreRebalancer.applyRangeRebalance), and when removing replicas
417+
// (Allocator.RemoveVoter).
418+
type BaseScorerOptionsNoConvergence struct {
419+
BaseScorerOptions
420+
}
421+
422+
var _ ScorerOptions = BaseScorerOptionsNoConvergence{}
423+
424+
// adjustRangeCountForScoring returns 0 since BaseScorerOptionsNoConvergence
425+
// does not want to consider range count in its scoring.
426+
func (bnc BaseScorerOptionsNoConvergence) adjustRangeCountForScoring(_ int) int {
427+
return 0
428+
}
429+
430+
// shouldRebalanceBasedOnThresholds returns false since
431+
// BaseScorerOptionsNoConvergence does not involve any heuristics that evaluate
432+
// stores within an equivalence class. If no rebalancing is needed based on
433+
// other attributes (e.g. valid, disk fullness, constraints, diversity score),
434+
// no rebalancing is done.
435+
func (bnc BaseScorerOptionsNoConvergence) shouldRebalanceBasedOnThresholds(
436+
_ context.Context, _ equivalenceClass, _ AllocatorMetrics,
437+
) bool {
438+
return false
439+
}
440+
441+
// balanceScore returns aroundTheMean for every store so that
442+
// BaseScorerOptionsNoConvergence does not take range count into account.
443+
func (bnc BaseScorerOptionsNoConvergence) balanceScore(
444+
_ storepool.StoreList, _ roachpb.StoreCapacity,
445+
) balanceStatus {
446+
return aroundTheMean
447+
}
448+
449+
// Note that the following three methods all return 0 for every store so that
450+
// BaseScorerOptionsNoConvergence does not take convergence score into account.
451+
// Important to keep them the same value since betterRebalanceTarget may compare
452+
// convergence score the difference between rebalanceFrom and rebalanceTo stores.
453+
func (bnc BaseScorerOptionsNoConvergence) rebalanceFromConvergesScore(_ equivalenceClass) int {
454+
return 0
455+
}
456+
func (bnc BaseScorerOptionsNoConvergence) rebalanceToConvergesScore(
457+
_ equivalenceClass, _ roachpb.StoreDescriptor,
458+
) int {
459+
return 0
460+
}
461+
func (bnc BaseScorerOptionsNoConvergence) removalMaximallyConvergesScore(
462+
_ storepool.StoreList, _ roachpb.StoreDescriptor,
463+
) int {
464+
return 0
465+
}
466+
404467
// RangeCountScorerOptions is used by the replicateQueue to tell the Allocator's
405468
// rebalancing machinery to base its balance/convergence scores on range counts.
406469
// This means that the resulting rebalancing decisions will further the goal of

pkg/kv/kvserver/allocator/plan/replicate.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,10 @@ func (rp ReplicaPlanner) ShouldPlanChange(
167167
voterReplicas := desc.Replicas().VoterDescriptors()
168168
nonVoterReplicas := desc.Replicas().NonVoterDescriptors()
169169
if !rp.knobs.DisableReplicaRebalancing {
170-
scorerOptions := rp.allocator.ScorerOptions(ctx)
170+
scorerOptions := allocatorimpl.ScorerOptions(rp.allocator.ScorerOptions(ctx))
171+
if rp.allocator.CountBasedRebalanceDisabled() {
172+
scorerOptions = rp.allocator.BaseScorerOptionsWithNoConvergence()
173+
}
171174
rangeUsageInfo := repl.RangeUsageInfo()
172175
_, _, _, ok := rp.allocator.RebalanceVoter(
173176
ctx,
@@ -790,6 +793,9 @@ func (rp ReplicaPlanner) considerRebalance(
790793
if scatter {
791794
scorerOpts = rp.allocator.ScorerOptionsForScatter(ctx)
792795
}
796+
if rp.allocator.CountBasedRebalanceDisabled() {
797+
scorerOpts = rp.allocator.BaseScorerOptionsWithNoConvergence()
798+
}
793799
rangeUsageInfo := repl.RangeUsageInfo()
794800
addTarget, removeTarget, details, ok := rp.allocator.RebalanceVoter(
795801
ctx,

0 commit comments

Comments
 (0)