Tokens are not refilled fully at Redis Cluster mode #477
-
Hello. my environment is this.
LettuceBasedProxyManager<byte[]> proxyManager = LettuceBasedProxyManager LettuceBasedProxyManager.builderFor(redisClusterClient)
.withExpirationStrategy(ExpirationAfterWriteStrategy.basedOnTimeForRefillingBucketUpToMax(
Duration.ofSeconds(1)))
.build();
String key = "bucket-key";
Bandwidth bandwidth = getCustomBandwidth(key); // choose bandwith
Bucket bucket = proxyManager.builder().build(key.getBytes(), () -> BucketConfiguration.builder().addLimit(bandwidth).build());
ConsumptionProbe probe = bucket.tryConsumeAndReturnRemaining(1);
canConsume = probe.isConsumed();
log.info("RateLimitFilter|key:{}|remain:{}|waitToRefill:{}ms", key, probe.getRemainingTokens(), probe.getNanosToWaitForRefill() / 1_000_000); public enum CustomBandwidth {
B_DEFAULT {
@Override
public Bandwidth getLimit() {
return Bandwidth.builder().capacity(100).refillIntervally(100, Duration.ofSeconds(1)).build();
}
},
B_200 {
@Override
public Bandwidth getLimit() {
return Bandwidth.builder().capacity(200).refillIntervally(200, Duration.ofSeconds(1)).build();
}
},
;
public abstract Bandwidth getLimit();
} Even though choosing B_200 which refill 200 for every second, printed log shows biggest remaining token is not 199 but 99.
This situation doesn't happen in my local environment and it only happen specific key.
I guess it would be related with high request rate. If my configuration is wrong, please let me know 😭 |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
Hello @NaayoungKwon
I do not think so. As mentioneed in Java docs, configuration supplier is not called if bucket is already persisted. You continue to observe capacity 100, that means that bucket was already persisted, when you deployed new code that uses new configs, and something activity prolongs lifetime of bucket that prevents bucket to be expired by TTL, so there is no chance for configuration supplier to be called. I suppose that previously you had only one configuration and splitted its later. There is two right way to apply configuration changes:
|
Beta Was this translation helpful? Give feedback.
-
Hello. @vladimir-bukhtoyarov the proxy manager is created as bean at spring and I choose bandwidth by requestor ip. am I right to understand?
I'll change like this. Bucket bucket = proxyManager.builder()
.withImplicitConfigurationReplacement(1, RESET)
.build(key.getBytes(), () -> BucketConfiguration.builder().addLimit(bandwidth).build()); Also, could you explain more about this? Does it mean, i have to change ExpirationAfterWriteStrategy?
|
Beta Was this translation helpful? Give feedback.
Hello @NaayoungKwon
I do not think so.
As mentioneed in Java docs, configuration supplier is not called if bucket is already persisted. You continue to observe capacity 100, that means that bucket was already persisted, when you deployed new code that uses new configs, and something activity prolongs lifetime of bucket that prevents bucket to be expired by TTL, so there is no chance for configuration supplier to be called. I suppose that previously you had only one configuration and splitted its later.
There is two right way to apply configuration changes:
I have l…