All four LoadBalancingStrategy options in redis/cluster.py are latency-blind: a degraded replica (GC pause, saturated host, cross-AZ hop) keeps its full read share until it fails outright, so read tail latency spikes long before errors appear.
Proposal: a LATENCY_BASED strategy using power-of-two-choices + peak-sensitive EWMA — pick two candidate nodes at random, route to the lower score = peak-EWMA of recent command latency × (in-flight + 1). O(1) per read, no probing; latency comes from command round-trips the client already performs. Zero required config, and slow cross-AZ replicas naturally deprioritize themselves.
I've implemented this algorithm in Apache brpc (apache/brpc#3367) and ClickHouse (ClickHouse/ClickHouse#109234); in brpc's benchmark with 1 degraded backend of 4, p99 dropped from 6.5ms (round-robin) to 337µs. Happy to open a PR with the strategy, tests, and docs if maintainers are open to it.
All four
LoadBalancingStrategyoptions inredis/cluster.pyare latency-blind: a degraded replica (GC pause, saturated host, cross-AZ hop) keeps its full read share until it fails outright, so read tail latency spikes long before errors appear.Proposal: a
LATENCY_BASEDstrategy using power-of-two-choices + peak-sensitive EWMA — pick two candidate nodes at random, route to the lower score = peak-EWMA of recent command latency × (in-flight + 1). O(1) per read, no probing; latency comes from command round-trips the client already performs. Zero required config, and slow cross-AZ replicas naturally deprioritize themselves.I've implemented this algorithm in Apache brpc (apache/brpc#3367) and ClickHouse (ClickHouse/ClickHouse#109234); in brpc's benchmark with 1 degraded backend of 4, p99 dropped from 6.5ms (round-robin) to 337µs. Happy to open a PR with the strategy, tests, and docs if maintainers are open to it.