Skip to content

fix: pin consistent-hash clients across weighted backendRefs - #9629

Open
guanchzhou wants to merge 1 commit into
envoyproxy:mainfrom
guanchzhou:eg-weighted-consistent-hash
Open

fix: pin consistent-hash clients across weighted backendRefs#9629
guanchzhou wants to merge 1 commit into
envoyproxy:mainfrom
guanchzhou:eg-weighted-consistent-hash

Conversation

@guanchzhou

Copy link
Copy Markdown
Contributor

What this PR does

Makes ConsistentHash load balancing pin a client to a single backend when a route splits traffic across multiple weighted backendRefs.

Problem

When a route has more than one weighted backend that needs a cluster-per-setting (e.g. per-backendRef filters, mixed endpoint types, weighted zones), Envoy Gateway renders the split as a weighted_clusters route action. The cluster selection among those weighted clusters is random per request. A route-level hash_policy (built from a ConsistentHash load balancer) only makes endpoint selection sticky within the chosen cluster — it does not govern which weighted cluster is picked. So with a canary/primary-backup split, a client can land on backend A for one request and backend B for the next, defeating consistent hashing.

Envoy exposes WeightedCluster.use_hash_policy: "If set, the router will use the request's hash policy to select the cluster." Envoy Gateway never set it.

Fixes #9626.

Change

In buildXdsRoute, after the route hash_policy is built, set use_hash_policy on the weighted clusters when the route action is a weighted_clusters action and a hash policy is present:

if wc := router.GetRoute().GetWeightedClusters(); wc != nil && len(router.GetRoute().GetHashPolicy()) > 0 {
    wc.RandomValueSpecifier = &routev3.WeightedCluster_UseHashPolicy{
        UseHashPolicy: wrapperspb.Bool(true),
    }
}

Gated on a hash policy being present, so weighted routes without a ConsistentHash load balancer are unaffected (their cluster selection stays random-by-weight, as before).

Testing

  • New fixture http-route-weighted-backend-consistent-hash — a weighted split across two backends (cluster-per-setting via per-backend filters) with a header-based ConsistentHash LB. The generated route now carries useHashPolicy: true alongside the hashPolicy.
  • The existing http-route-weighted-zones golden updated: only the route that has both a ConsistentHash LB and weighted clusters gains useHashPolicy: true; weighted routes without a hash policy are untouched — demonstrating the gating.
go build ./...                          # ok
go test ./internal/xds/...              # ok
gofmt -l / go vet                       # clean

When a route splits traffic across multiple weighted backendRefs and uses a ConsistentHash
load balancer, Envoy Gateway rendered the split as a weighted_clusters route action whose
cluster selection is random per request. The route hash policy only pinned endpoint selection
within a cluster, so a client was not pinned to a single backend across the split.

Set WeightedCluster.use_hash_policy on the generated weighted clusters when a hash policy is
present, so Envoy selects the weighted cluster deterministically from the request's hash policy
instead of at random. Gated on a hash policy being configured, so non-ConsistentHash weighted
routes are unaffected.

Fixes envoyproxy#9626

Signed-off-by: Andrey Maltsev <maltsev.andrey@gmail.com>
@guanchzhou
guanchzhou requested a review from a team as a code owner July 31, 2026 11:54
@netlify

netlify Bot commented Jul 31, 2026

Copy link
Copy Markdown

Deploy Preview for cerulean-figolla-1f9435 ready!

Name Link
🔨 Latest commit 648587c
🔍 Latest deploy log https://app.netlify.com/projects/cerulean-figolla-1f9435/deploys/6a6c8cddbf6e390008561cca
😎 Deploy Preview https://deploy-preview-9629--cerulean-figolla-1f9435.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.06%. Comparing base (b710dd4) to head (648587c).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9629      +/-   ##
==========================================
+ Coverage   76.04%   76.06%   +0.02%     
==========================================
  Files         259      259              
  Lines       43275    43278       +3     
==========================================
+ Hits        32907    32919      +12     
+ Misses       8178     8170       -8     
+ Partials     2190     2189       -1     

☔ 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@arkodg arkodg added this to the v1.9.0 Release milestone Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ConsistentHash LB does not pin clients across weighted backendRefs (set WeightedCluster.use_hash_policy)

2 participants