-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Support sharding in RedisRateLimiter #3780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: liufangzhou.aaa <[email protected]>
int getShardedReplenishRate(Config config) { | ||
int replenishRate = config.getReplenishRate(); | ||
if (config.getShards() > 0) { | ||
replenishRate = replenishRate / config.getShards(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if replenishRate
is could not be divisible by shards, the actual rate will less than replenishRate
, reminder value should be considered.
Very useful feature. The purpose of rate limiting is to protect downstream services from overload. However, in such as e-commerce platforms promotion scenarios almost all requests are concentrated on a hot resource. Since the same resources use the same rate limiting key, they will continuously request the same redis shard, causing redis overload. In order not to affect business functions when redis is overloaded, we will let it go of the request, resulting in failure to achieve the expected rate limiting effect. And because the same rate limiting key always requests the same redis shard, we cannot improve system stability through distributed computing under the original implementation. I have carefully read the implementation of the code. By adding suffixes to the rate limiting key to obtain different hashtags, the requests can be dispersed to different redis shards to avoid single instance overload. In addition to avoiding single machine overload, since Lua scripts can be executed on different redis instances at the same time, this will greatly improve the parallelism of rate limiting. |
/** | ||
* A Round-Robin like index to select a virtual shard. | ||
*/ | ||
private final AtomicInteger shardIndex = new AtomicInteger(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why using Round-Robin?
Problem Statement:
The current implementation of RedisRateLimiter uses a single Redis key for rate limiting counters. This leads to a hot key problem in Redis clusters, where massive requests concentrate on a single Redis shard. The resulting excessive load on individual shards cannot be alleviated through horizontal cluster scaling, creating a performance bottleneck.
Proposed Solution:
This PR introduces a shards configuration parameter to address the hot key issue. Key enhancements include: