Skip to content

scheduler, evict-slow-store allow draining multiple store from AZ#10743

Open
Tema wants to merge 4 commits into
tikv:masterfrom
Tema:tema/evict-slow-score-ci
Open

scheduler, evict-slow-store allow draining multiple store from AZ#10743
Tema wants to merge 4 commits into
tikv:masterfrom
Tema:tema/evict-slow-score-ci

Conversation

@Tema

@Tema Tema commented May 30, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: Close #10742

What is changed and how does it work?

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)

Use chaos mesh to emulate slow disk

apiVersion: chaos-mesh.org/v1alpha1
kind: IOChaos
metadata:
  name: tikv-0
  namespace: chaos-mesh
spec:
  action: latency
  mode: one
  selector:
    namespaces:
      - tidb-dev-test
    labelSelectors:
      'app.kubernetes.io/component': 'tikv'
    fieldSelectors:
      'metadata.name': 'dev-test-tikv-0'
  volumePath: /var/lib/raft
  delay: 100ms
  percent: 100
  duration: '900s'

Verify default behavior:

  • only first slow node gets drained even in the same AZ
image

Enabling the feature:

  • pd-ctl scheduler config evict-slow-store-scheduler set group-eviction-labels "zone"
  • Inject disk delay to first node in zone A
  • Observe leaders started to drop
  • Inject disk delay to a node in zone B
  • No additional leaders dropped
  • Inject disk delay to a second node in zone A
  • No additional leaders dropped
  • Remove disk delay from the node in zone B
  • Leaders are dropping for the second node in zone A
image
  • No code

Code changes

Side effects

  • Possible performance regression
  • Increased code complexity
  • Breaking backward compatibility

Related changes

Release note

None.

Summary by CodeRabbit

  • New Features

    • Grouped multi-store disk slow-store eviction via configurable eviction labels (comma-separated input) for coordinated domain drains; scheduler now reports multi-store eviction state and blocks scheduling while any disk eviction is active.
  • Bug Fixes / Reliability

    • Safer persistence and recovery for eviction sets with robust add/remove/clear semantics and improved lifecycle handling.
  • Tests

    • Expanded unit and end-to-end tests for group eviction, reconciliation, recovery, and edge cases.

@ti-chi-bot ti-chi-bot Bot added release-note-none Denotes a PR that doesn't merit a release note. dco-signoff: yes Indicates the PR's author has signed the dco. contribution This PR is from a community contributor. needs-ok-to-test Indicates a PR created by contributors and need ORG member send '/ok-to-test' to start testing. labels May 30, 2026
@ti-chi-bot

ti-chi-bot Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

Hi @Tema. Thanks for your PR.

I'm waiting for a tikv member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Evict-slow-store moves from single-store to group-aware eviction: config now persists label-driven eviction groups and a set of evicted store IDs; lifecycle and leader marking handle batched evictions; scheduling blocks while any disk eviction is active; algorithm starts, reconciles, expands, or releases multi-store drains based on configured failure-domain labels and topology capacity.

Changes

Disk slow store eviction refactor

Layer / File(s) Summary
Config state and persistence model
pkg/schedule/schedulers/evict_slow_store.go
Config now exposes evictedStores() (snapshot copy) and isEvictingDiskSlowStore() multi-store predicate. Persistence helpers shift from single-ID to set-based: setEvictedStoresAndPersist, removeEvictedAndPersist, and rewritten clearEvictedAndPersist that returns all previously evicted IDs and resets the recovery clock.
HTTP parsing and reload
pkg/schedule/schedulers/evict_slow_store.go
Adds parseGroupEvictionLabels to convert comma-separated input into trimmed non-empty label slices, persists GroupEvictionLabels via the /config path, and restores it on reload. PrepareConfig reapplies SlowStoreEvicted for every persisted evicted store ID.
Scheduler lifecycle and leader marking
pkg/schedule/schedulers/evict_slow_store.go
prepareEvictLeader now accepts batches and rolls back on failure; cleanupEvictLeader recovers all cleared evicted stores and removes per-store gauge labels. IsScheduleAllowed blocks scheduling while any disk eviction is active.
Zone-aware group eviction algorithm
pkg/schedule/schedulers/evict_slow_store.go
scheduleDiskSlowStore collects slow stores and starts group eviction only when multiple slow stores share the configured failure-domain labels and enough healthy domains remain. reconcileDiskSlowStoreGroup manages ongoing group state: drops removed stores, tracks recovery using max slow score, freezes expansion when the locked domain becomes invalid, and expands only with capacity safeguards.
Test infrastructure and comprehensive test suite
pkg/schedule/schedulers/evict_slow_store_test.go, server/cluster/cluster_test.go
Adds metapb import and new helpers for label-based group eviction and slow-score simulation. Migrates existing tests to multi-store assertions, adds many new unit tests for label-driven behavior, and an end-to-end test that reconfigures the scheduler via HTTP and verifies group eviction across labeled stores.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Scheduler
  participant Topology
  participant PersistedState
  Client->>Scheduler: POST /config (group-eviction-labels)
  Scheduler->>PersistedState: persist GroupEvictionLabels
  Scheduler->>Topology: collect slow stores
  Scheduler->>Scheduler: evaluate domain co-location & healthy domains
  Scheduler->>PersistedState: setEvictedStoresAndPersist(groupIDs)
  Scheduler->>Topology: prepareEvictLeader(cluster, addIDs)
  Topology->>Scheduler: leader eviction status / recovery signals
  Scheduler->>PersistedState: removeEvictedAndPersist/clearEvictedAndPersist on reconcile/release
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 I sniff the labels, one zone in sight,
I herd the slow stores through the night.
When other zones stand ready and bright,
We drain the group and hold on tight.
At dawn the leaders hop back — delight.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 67.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: enabling group eviction of multiple stores from the same AZ in the evict-slow-store scheduler.
Description check ✅ Passed The description covers all required sections including issue number, problem statement with test plans, code changes verified, and addresses all main checklist categories.
Linked Issues check ✅ Passed All coding requirements from issue #10742 are met: uniform placement-rule isolation checks, same-AZ grouping, healthy-zone validation, freeze on multi-zone slow detection, and group recovery logic are implemented.
Out of Scope Changes check ✅ Passed All changes are directly scoped to enable AZ-aware group eviction in the evict-slow-store scheduler without modifying other slow-store mechanisms as intended.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ti-chi-bot ti-chi-bot Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label May 30, 2026
@Tema
Tema force-pushed the tema/evict-slow-score-ci branch from 9b03ea3 to bfc522d Compare May 30, 2026 01:03

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
pkg/response/easyjson-bootstrap4020482302.go (1)

1-4: 💤 Low value

Use modern build constraint syntax and fix typo.

Line 1: Go 1.17+ prefers //go:build ignore over the older // +build ignore.
Line 3: Typo "bootstapping" → "bootstrapping".

-// +build ignore
+//go:build ignore

-// TEMPORARY AUTOGENERATED FILE: easyjson bootstapping code to launch
+// TEMPORARY AUTOGENERATED FILE: easyjson bootstrapping code to launch
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/response/easyjson-bootstrap4020482302.go` around lines 1 - 4, Replace the
old build constraint and fix the typo: change the first-line build tag from "//
+build ignore" to the modern "//go:build ignore" and correct the misspelled word
"bootstapping" to "bootstrapping" in the comment describing the autogenerated
file (the header comment in easyjson-bootstrap4020482302.go).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/response/region_easyjson.go`:
- Line 11: The stubbed MarshalJSON implementations (e.g., MetaPeer.MarshalJSON)
currently return (nil, nil) which will silently produce null JSON; change each
stub (MetaPeer.MarshalJSON and the similar stubs for PDPeerStats.MarshalJSON,
RegionInfo.MarshalJSON, RegionsInfo.MarshalJSON, ReplicationStatus.MarshalJSON)
to fail loudly by returning a non-nil error (or panic with a clear message)
indicating that the method is not implemented/auto-generated code is out of date
so callers get an explicit failure rather than silent nulls.
- Line 4: The package declaration has an extra space ("package  response");
update it to a single-space package declaration ("package response") in the file
containing region_easyjson.go and run the repository formatter (e.g., make fmt)
to apply and verify formatting; change the package line only (the symbol to
locate is the package declaration at the top of region_easyjson.go).

---

Nitpick comments:
In `@pkg/response/easyjson-bootstrap4020482302.go`:
- Around line 1-4: Replace the old build constraint and fix the typo: change the
first-line build tag from "// +build ignore" to the modern "//go:build ignore"
and correct the misspelled word "bootstapping" to "bootstrapping" in the comment
describing the autogenerated file (the header comment in
easyjson-bootstrap4020482302.go).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a69917e9-7ee2-4871-9dcb-61690044e5f9

📥 Commits

Reviewing files that changed from the base of the PR and between 9b03ea3 and bfc522d.

📒 Files selected for processing (5)
  • pkg/response/easyjson-bootstrap4020482302.go
  • pkg/response/region_easyjson.go
  • pkg/response/region_easyjson.go.tmp
  • pkg/schedule/schedulers/evict_slow_store.go
  • pkg/schedule/schedulers/evict_slow_store_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/schedule/schedulers/evict_slow_store_test.go

Comment thread pkg/response/region_easyjson.go Outdated
Comment thread pkg/response/region_easyjson.go Outdated
Signed-off-by: artem_danilov <artem.danilov@airbnb.com>
@Tema
Tema force-pushed the tema/evict-slow-score-ci branch from bfc522d to 1dd3803 Compare May 30, 2026 01:46
@Tema

Tema commented May 30, 2026

Copy link
Copy Markdown
Contributor Author

/retest

@ti-chi-bot

ti-chi-bot Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

@Tema: Cannot trigger testing until a trusted user reviews the PR and leaves an /ok-to-test message.

Details

In response to this:

/retest

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@Tema

Tema commented May 30, 2026

Copy link
Copy Markdown
Contributor Author

/ok-to-test

@ti-chi-bot

ti-chi-bot Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

@Tema: Cannot trigger testing until a trusted user reviews the PR and leaves an /ok-to-test message.

Details

In response to this:

/ok-to-test

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@okJiang

okJiang commented Jun 1, 2026

Copy link
Copy Markdown
Member

/ok-to-test

@ti-chi-bot ti-chi-bot Bot added ok-to-test Indicates a PR is ready to be tested. and removed needs-ok-to-test Indicates a PR created by contributors and need ORG member send '/ok-to-test' to start testing. labels Jun 1, 2026
@Tema

Tema commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

/retest-required

@Tema

Tema commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author
--- FAIL: TestKeyspaceGroupTestSuite (89.36s)
              --- PASS: TestKeyspaceGroupTestSuite/TestAllocNodes (3.08s)
              --- PASS: TestKeyspaceGroupTestSuite/TestAllocNodesUpdate (1.92s)
              --- PASS: TestKeyspaceGroupTestSuite/TestAllocOneNode (3.65s)
              --- PASS: TestKeyspaceGroupTestSuite/TestAllocReplica (3.41s)
              --- PASS: TestKeyspaceGroupTestSuite/TestDefaultKeyspaceGroup (3.70s)
              --- PASS: TestKeyspaceGroupTestSuite/TestSetNodes (1.55s)
              --- FAIL: TestKeyspaceGroupTestSuite/TestUpdateMemberWhenRecovery (72.06s)

@Tema

Tema commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

/retest-required

@okJiang

okJiang commented Jun 2, 2026

Copy link
Copy Markdown
Member

/retest

@codecov

codecov Bot commented Jun 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.93151% with 33 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.19%. Comparing base (bde1fe9) to head (8ec57c9).
⚠️ Report is 9 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #10743      +/-   ##
==========================================
+ Coverage   79.16%   79.19%   +0.02%     
==========================================
  Files         536      536              
  Lines       73609    74034     +425     
==========================================
+ Hits        58273    58631     +358     
- Misses      11235    11280      +45     
- Partials     4101     4123      +22     
Flag Coverage Δ
unittests 79.19% <84.93%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment on lines +857 to +872
// groupIsolationKey returns the label key to group slow stores by. Group eviction
// is only allowed when every placement rule enforces the same non-empty isolation
// level, so draining a single zone is known to be safe for every region.
func groupIsolationKey(cluster sche.SchedulerCluster) (string, bool) {
rules := cluster.GetRuleManager().GetAllRules() // includes default one
if len(rules) == 0 || rules[0].IsolationLevel == "" {
return "", false
}
level := rules[0].IsolationLevel
for _, r := range rules[1:] {
if r.IsolationLevel != level {
return "", false
}
}
return level, true
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not recommended to use IsolationLevel as a target filter label.

A more appropriate approach is to add a manual configuration that determines whether the slow stores belong to the same availability zone (AZ). And the comparison logic should consider that the configuration value could be a multi-level labels, i.e. zone or zone, rack.

For example, we could name the configuration evicting-label and set it as follows:

  • evicting-label: zone: Multi-node leader eviction is triggered only when the slow stores share the same zone label.
  • evicting-label: zone, rack: Multi-node leader eviction is triggered only when the slow stores share both the same zone and rack labels.
  • Empty (default): The default evicting strategy applies, which falls back to the original design — evicting a single slow node.

The comparison logic can be referenced from:

pd/pkg/core/store.go

Lines 691 to 703 in 51b1226

// CompareLocation compares 2 stores' labels and returns at which level their
// locations are different. It returns -1 if they are at the same location.
func (s *StoreInfo) CompareLocation(other *StoreInfo, labels []string) int {
for i, key := range labels {
v1, v2 := s.GetLabelValue(key), other.GetLabelValue(key)
// If label is not set, the store is considered at the same location
// with any other store.
if v1 != "" && v2 != "" && !strings.EqualFold(v1, v2) {
return i
}
}
return -1
}
.

Rest LGTM.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not recommended to use IsolationLevel as a target filter label.

I'm curious why not? Just to make it configurable differently? I feel if it does not match isolation expectations, it can lead to issues.

Anyway, I don't have a strong opinion on that and like an option to turn it on/off, so I've added group-eviction-labels into PD scheduler config as you recommended. @LykxSassinator PTAL

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct me if I'm wrong. /cc @rleungx

FYI, isolation-level is used to determine the HA level for the entire TiKV cluster, not to determine the AZ of individual TiKV nodes.

  • By default, this value is empty. This means that regardless of the AZs in which TiKV nodes are deployed, if some TiKV nodes go down (marked as the Down state), PD will add replicas on other alive TiKV nodes to ensure overall HA stability — irrespective of the AZs of the TiKV nodes.
  • If isolation-level is set to zone in a three‑AZ deployment, and one AZ goes down, PD will not trigger operations to add replicas in other AZs, because the isolation level is constrained to zone.

In other words, isolation-level is not the actual tag that reflects which AZ a TiKV node is deployed in. In fact, LocationLabel is used to mark the deployment tag that indicates the location of a given TiKV node.

Regarding my earlier suggestion:

"A more appropriate approach is to add a manual configuration ..."

On one hand, we want to introduce an extra, clear configuration to explicitly enable or disable this newly introduced feature. On the other hand, by allowing users to manually set this configuration based on their requests, users can control the evicting strategy themselves if multiple TiKV nodes exist, exactly as they expect.

@LykxSassinator LykxSassinator Jul 9, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After further discussion, I think we should keep this PR simple and revert to the previous isolation-based direction.

The current group-eviction-labels config feels unnecessary here. It is not well aligned with the semantics of IsolationLevel, and it adds extra config, validation, and operational cost for what should be a focused correctness fix.

But the old implementation still needs one fix: it treated IsolationLevel as a single label key, while PD's actual isolation semantics are based on the LocationLabels prefix up to and including IsolationLevel.

So for this PR, I suggest:

  • revert to the previous isolation-based design;
  • fix the implementation to compare the LocationLabels prefix up to IsolationLevel, instead of only store.GetLabelValue(IsolationLevel);
  • keep the original conservative rule that grouping is allowed only when all placement rules share the same non-empty IsolationLevel;
  • add only a simple boolean on/off switch so this feature can be explicitly disabled.

This keeps the change aligned with PD's existing isolation model, fixes the real bug, and avoids turning this PR into a broader config-policy discussion.

@Tema PTAL

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@HaoW30 PTAL.

Signed-off-by: artem_danilov <artem.danilov@airbnb.com>
@Tema

Tema commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

/retest-required

@Tema

Tema commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

/test pull-unit-test-next-gen-3

@LykxSassinator

Copy link
Copy Markdown
Contributor

/retest

@LykxSassinator

Copy link
Copy Markdown
Contributor

/cc @okJiang @rleungx

@ti-chi-bot
ti-chi-bot Bot requested a review from okJiang June 3, 2026 10:42
@ti-chi-bot
ti-chi-bot Bot requested a review from rleungx June 3, 2026 10:42
@LykxSassinator

Copy link
Copy Markdown
Contributor

/retest

Signed-off-by: artem_danilov <artem.danilov@airbnb.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
server/cluster/cluster_test.go (1)

3521-3610: 🏗️ Heavy lift

Exercise actual leader movement in this e2e case.

Every assertion here is against EvictedAsSlowStore(), so this can stay green even if the coordinator never drains any leaders or if leaders come back before the whole zone has recovered. Since the docstring/comments describe end-to-end eviction and recovery ordering, seed a few real regions and assert leader counts or transfer operators move off z1 and only return after all three stores recover.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/cluster/cluster_test.go` around lines 3521 - 3610, The test currently
only asserts EvictedAsSlowStore(), so add real leader movement checks: seed
several regions with leaders pinned to stores 1,2,3 at the start (use the test
cluster helper methods that create regions with a specific leader on a store via
tc.AddRegion / tc.PutRegion / whatever region-seeding helper exists), then after
calling markSlow to trigger group eviction assert that the leader count on zone
"z1" (query via tc.RegionStoreLeaderCount or by iterating tc.Regions and
counting leaders on store IDs 1,2,3) goes to zero (or that transfer operators
off z1 are created) and remains off until all three stores have been recovered
(call markSlow(1,0); markSlow(2,0); markSlow(3,0) and then assert leaders are
returned to z1), while keeping the existing EvictedAsSlowStore() assertions;
reference TestEvictSlowStoreGroupEviction, markSlow, tc.GetStore and
EvictedAsSlowStore() to locate where to insert region seeding and leader-count
assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@server/cluster/cluster_test.go`:
- Around line 3521-3610: The test currently only asserts EvictedAsSlowStore(),
so add real leader movement checks: seed several regions with leaders pinned to
stores 1,2,3 at the start (use the test cluster helper methods that create
regions with a specific leader on a store via tc.AddRegion / tc.PutRegion /
whatever region-seeding helper exists), then after calling markSlow to trigger
group eviction assert that the leader count on zone "z1" (query via
tc.RegionStoreLeaderCount or by iterating tc.Regions and counting leaders on
store IDs 1,2,3) goes to zero (or that transfer operators off z1 are created)
and remains off until all three stores have been recovered (call markSlow(1,0);
markSlow(2,0); markSlow(3,0) and then assert leaders are returned to z1), while
keeping the existing EvictedAsSlowStore() assertions; reference
TestEvictSlowStoreGroupEviction, markSlow, tc.GetStore and EvictedAsSlowStore()
to locate where to insert region seeding and leader-count assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1ed2246d-13d9-4897-a1ca-fc25103dac20

📥 Commits

Reviewing files that changed from the base of the PR and between 61734f7 and 109d271.

📒 Files selected for processing (1)
  • server/cluster/cluster_test.go

@LykxSassinator

Copy link
Copy Markdown
Contributor

/retest

Signed-off-by: artem_danilov <artem.danilov@airbnb.com>
@Tema

Tema commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

/retest-required

@ti-chi-bot

ti-chi-bot Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

@LykxSassinator: adding LGTM is restricted to approvers and reviewers in OWNERS files.

Details

In response to this:

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@ti-chi-bot

ti-chi-bot Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: LykxSassinator
Once this PR has been reviewed and has the lgtm label, please assign overvenus for approval. For more information see the Code Review Process.
Please ensure that each of them provides their approval before proceeding.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

func hasEnoughHealthyDomains(cluster sche.SchedulerCluster, labels []string, drained *core.StoreInfo) bool {
reps := make([]*core.StoreInfo, 0, minRemainingHealthyDomains)
for _, store := range cluster.GetStores() {
if !store.IsUp() || store.IsSlow() || store.EvictedAsSlowStore() || !store.AllowLeaderTransferIn() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the same target-store checks as leader transfer here? This predicate can count stores that StoreStateFilter{TransferLeader: true} later rejects (down, disconnected, busy, reject-leader), so group eviction may start without two real healthy target domains.

@LykxSassinator LykxSassinator Jul 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, you can use a helper function to take the same filtering condition as "leader transfer" does, for example:

func eligibleHealthyLeaderTargets(cluster sche.SchedulerCluster, stores []*core.StoreInfo) []*core.StoreInfo {
    candidates := filter.NewCandidates(stores).
        FilterTarget(
            cluster.GetSchedulerConfig(),
            nil,
            nil,
            &filter.StoreStateFilter{
                ActionScope:  types.EvictSlowStoreScheduler.String(),
                TransferLeader: true,
                OperatorLevel:  constant.Urgent,
            },
        ).
        PickAll()

    healthy := candidates[:0]
    // Filter out already slow nodes
    for _, store := range candidates {
        if store.IsSlow() {
            continue
        }
        healthy = append(healthy, store)
    }
    return healthy
}

@okJiang okJiang left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from existing comments, lgtm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contribution This PR is from a community contributor. dco-signoff: yes Indicates the PR's author has signed the dco. ok-to-test Indicates a PR is ready to be tested. release-note-none Denotes a PR that doesn't merit a release note. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

evict-slow-store: allow draining multiple nodes from the same availability zone

4 participants