-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
About ping command routing in validateConnection with Redis Cluster #3081
Comments
After further read of related issues, I found this comment #1470 (comment) :
This led me to review the
While the API documentation doesn't explicitly state "only intended for standalone",but my application doesn't actively close connections, so it seems I can safely disable The |
|
Thank you for taking the time to reply to this issue. Initially, because Upon further investigation, I confirmed the default node selection logic for private <K, V> CompletableFuture<StatefulRedisClusterConnection<K, V>> connectClusterAsync(RedisCodec<K, V> codec) {
if (partitions == null) {
return Futures.failed(new IllegalStateException(
"Partitions not initialized. Initialize via RedisClusterClient.getPartitions()."));
}
activateTopologyRefreshIfNeeded();
logger.debug("connectCluster(" + initialUris + ")");
//sortByClientCount
Mono<SocketAddress> socketAddressSupplier = getSocketAddressSupplier(TopologyComparators::sortByClientCount);
//defualt writer
DefaultEndpoint endpoint = new DefaultEndpoint(clientOptions, clientResources);
RedisChannelWriter writer = endpoint;
if (CommandExpiryWriter.isSupported(clientOptions)) {
writer = new CommandExpiryWriter(writer, clientOptions, clientResources);
}
ClusterDistributionChannelWriter clusterWriter = new ClusterDistributionChannelWriter(clientOptions, writer,
clusterTopologyRefreshScheduler);
PooledClusterConnectionProvider<K, V> pooledClusterConnectionProvider = new PooledClusterConnectionProvider<>(this,
clusterWriter, codec, clusterTopologyRefreshScheduler);//defualt writer
clusterWriter.setClusterConnectionProvider(pooledClusterConnectionProvider);
StatefulRedisClusterConnectionImpl<K, V> connection = new StatefulRedisClusterConnectionImpl<>(clusterWriter, codec,
timeout);
connection.setReadFrom(ReadFrom.MASTER);
connection.setPartitions(partitions);
Supplier<CommandHandler> commandHandlerSupplier = () -> new CommandHandler(clientOptions, clientResources, endpoint);
Mono<StatefulRedisClusterConnectionImpl<K, V>> connectionMono = Mono
.defer(() -> connect(socketAddressSupplier, codec, endpoint, connection, commandHandlerSupplier));
for (int i = 1; i < getConnectionAttempts(); i++) {
connectionMono = connectionMono
.onErrorResume(t -> connect(socketAddressSupplier, codec, endpoint, connection, commandHandlerSupplier));
}
return connectionMono.flatMap(c -> c.reactive().command().collectList() //
.map(CommandDetailParser::parse) //
.doOnNext(detail -> c.setState(new RedisState(detail))) //
.doOnError(e -> c.setState(new RedisState(Collections.emptyList()))).then(Mono.just(c))
.onErrorResume(RedisCommandExecutionException.class, e -> Mono.just(c)))
.doOnNext(
c -> connection.registerCloseables(closeableResources, clusterWriter, pooledClusterConnectionProvider))
.map(it -> (StatefulRedisClusterConnection<K, V>) it).toFuture();
} |
Environments:
Issue:
When using
RedisTemplate.execute(conn->conn.incrBy(key,delt))
, I observed that some microservicesPING
a slave node before sending theINCR
command to the correct master node.Through debugging, I found the following logic: The
PING
command uses thedefaultWriter
because it has no parameters, unlike theINCR
command which is routed to a specific master node.spring-data-redis/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactory.java
Line 1210 in f9de805
spring-data-redis/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactory.java
Line 1623 in b529e83
https://github.com/redis/lettuce/blob/55ebef8b5c095869aecf8cea8eb9eb5da585badf/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java#L999
https://github.com/redis/lettuce/blob/55ebef8b5c095869aecf8cea8eb9eb5da585badf/src/main/java/io/lettuce/core/cluster/ClusterDistributionChannelWriter.java#L114-L115
https://github.com/redis/lettuce/blob/b396f621cbc6e88cd50e9e117addcaecf040abca/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java#L1902
https://github.com/redis/lettuce/blob/b396f621cbc6e88cd50e9e117addcaecf040abca/src/main/java/io/lettuce/core/cluster/ClusterDistributionChannelWriter.java#L172-L173
I suspect this behavior is due to the routing logic shown above.
I've been searched Google for "spring-data-redis validateConnection ping" and "spring-data-redis validateConnection ping slave", and also searched for "validateConnection" in the issues, but found no relevant information.
Questions
I'm currently diving deeper into the source code. Any insights or confirmation would be greatly appreciated.
The text was updated successfully, but these errors were encountered: