Skip to content

Fix skewed search replica request distribution when write replicas exist#22528

Open
mars2cbh wants to merge 2 commits into
opensearch-project:mainfrom
mars2cbh:fix-search-replica-rotation-skew
Open

Fix skewed search replica request distribution when write replicas exist#22528
mars2cbh wants to merge 2 commits into
opensearch-project:mainfrom
mars2cbh:fix-search-replica-rotation-skew

Conversation

@mars2cbh

@mars2cbh mars2cbh commented Jul 21, 2026

Copy link
Copy Markdown

Description

IndexShardRoutingTable#filterAndOrderShards (used by searchReplicaActiveInitializingShardIt() / the _search_replica preference path) rotated the full replicas list before applying the search-only filter. RotationShardShuffler is a pure round-robin rotation, so rotation offsets that land on a filtered-out write replica collapse onto the same head shard as the adjacent offset. In a reader/writer separated cluster with one write replica and n search replicas, the search replica that precedes the write replica in list order becomes the iterator head for two of the n+1 rotation offsets, permanently receiving a 2/(n+1) share of search traffic (exactly 2x the others). With replicas = [W, S1, S2, S3]:

rotation offset rotated list iterator head
0 W, S1, S2, S3 S3
1 S1, S2, S3, W S3
2 S2, S3, W, S1 S1
3 S3, W, S1, S2 S2

This change applies the filter first and rotates only the filtered active list, restoring a uniform round-robin. Active shards still come before initializing ones. replicaActiveInitializingShardIt() (filter accepts everything, so no offset collapse) and the zero-write-replica case keep their previous uniform behavior.

Added tests:

  • testSearchReplicaShardIteratorEvenDistribution — randomizes 0–3 write replicas, 2–5 search replicas, and list order, then asserts each search replica is the iterator head an exactly equal number of times. Fails on the old implementation whenever a write replica is present.
  • testSearchReplicaShardIteratorReturnsActiveBeforeInitializing — asserts only search replicas are returned, active before initializing.

Related Issues

Resolves #22527

Check List

  • Functionality includes testing.
  • API changes companion pull request created, if applicable.
  • Public documentation issue/PR created, if applicable.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

@mars2cbh
mars2cbh requested a review from a team as a code owner July 21, 2026 13:42
@github-actions github-actions Bot added the Search Search query, autocomplete ...etc label Jul 21, 2026
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

(Review updated until commit 0243728)

Here are some key observations to aid the review process:

🧪 PR contains tests
🔒 No security concerns identified
✅ No TODO sections
🔀 No multiple PR themes
⚡ No major issues detected

@mars2cbh
mars2cbh force-pushed the fix-search-replica-rotation-skew branch from 8eb6487 to 6925ae6 Compare July 21, 2026 13:45
@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit 6925ae6

@github-actions

Copy link
Copy Markdown
Contributor

❌ Gradle check result for 6925ae6: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

filterAndOrderShards rotated the full replicas list before filtering, so
rotation offsets landing on filtered-out write replicas collapsed onto the
same search replica, giving it a fixed 2/(n+1) share of requests in
reader/writer separated clusters. Filter first, then rotate only the
matching active replicas so the round-robin stays uniform.

Signed-off-by: David Choi <themars@gmail.com>
@mars2cbh
mars2cbh force-pushed the fix-search-replica-rotation-skew branch from 6925ae6 to bea0a45 Compare July 21, 2026 14:22
@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit bea0a45

@github-actions

Copy link
Copy Markdown
Contributor

✅ Gradle check result for bea0a45: SUCCESS

@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.44%. Comparing base (0213338) to head (bea0a45).

Additional details and impacted files
@@             Coverage Diff              @@
##               main   #22528      +/-   ##
============================================
- Coverage     73.48%   73.44%   -0.04%     
+ Complexity    76460    76451       -9     
============================================
  Files          6104     6104              
  Lines        346582   346586       +4     
  Branches      49879    49879              
============================================
- Hits         254675   254543     -132     
- Misses        71664    71782     +118     
- Partials      20243    20261      +18     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

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

@github-actions

Copy link
Copy Markdown
Contributor

Persistent review updated to latest commit 0243728

@github-actions

Copy link
Copy Markdown
Contributor

✅ Gradle check result for 0243728: SUCCESS

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

Labels

Search Search query, autocomplete ...etc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Search replica routing skews a fixed 2/(n+1) traffic share onto one search replica when write replicas exist

1 participant