Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
7910819
Implemented read-write separation based on JedisSentineled
Aug 18, 2025
610aac4
test ut
Aug 25, 2025
d1b9d0b
feat(read): 增加读取策略配置
Sep 8, 2025
5063c11
Implemented read-write separation based on JedisSentineled
Sep 8, 2025
9c0578d
add ut
Sep 8, 2025
ae74a40
add ut
Sep 9, 2025
3b91b6c
format file
Sep 17, 2025
e02656c
Merge branch 'master' into sentineledSlavePool
Sep 17, 2025
da4d377
format ReadOnlyCommands.java
Sep 25, 2025
ab0c82c
format ReadOnlyCommands.java
Sep 25, 2025
5c34820
format ReadOnlyCommands.java
Sep 25, 2025
26a2dc5
Merge branch 'master' into sentineledSlavePool
Oct 10, 2025
c30d960
remove unused import
Oct 10, 2025
6d0f6c8
remove unused import
Oct 10, 2025
07c99d9
fix JedisSentineled builder
Oct 17, 2025
8a4d9cb
fix JedisSentineled builder
Oct 17, 2025
5dd46cd
fix JedisSentineled builder
Oct 17, 2025
95171b1
fix JedisSentineled builder
Oct 17, 2025
fd38283
fix JedisSentineled builder
Oct 17, 2025
f17b58a
format
Oct 20, 2025
a1b28e8
fix test
Oct 20, 2025
0e219cd
Merge branch 'master' into sentineledSlavePool
Oct 22, 2025
6d35b69
Merge branch 'master' into sentineledSlavePool
Nov 6, 2025
db3c263
use CommandFlags
Nov 6, 2025
151293b
format
Nov 6, 2025
1b11299
Merge branch 'master' into sentineledSlavePool
ggivo Nov 19, 2025
8788412
Merge remote-tracking branch 'upstream/master' into sentineledSlavePool
Nov 20, 2025
932c50b
bugfix
Nov 20, 2025
c621d9f
Merge remote-tracking branch 'origin/sentineledSlavePool' into sentin…
Nov 20, 2025
14d7989
Merge remote-tracking branch 'upstream/master' into sentineledSlavePool
Nov 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,12 @@
<version>${resilience4j.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-circuitbreaker</artifactId>
Expand Down Expand Up @@ -546,6 +552,7 @@
<include>**/*CommandFlags*.java</include>
<include>**/*CompareCondition*.java</include>
<include>**/*MSetExParams*.java</include>
<include>src/main/java/redis/clients/jedis/util/ReadOnlyCommands.java</include>
<include>**/*UnitTest.java</include>
</includes>
</configuration>
Expand Down
18 changes: 17 additions & 1 deletion src/main/java/redis/clients/jedis/JedisSentineled.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package redis.clients.jedis;

import java.util.Set;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.annots.Experimental;
import redis.clients.jedis.builders.SentinelClientBuilder;
Expand All @@ -11,6 +10,8 @@
import redis.clients.jedis.providers.ConnectionProvider;
import redis.clients.jedis.providers.SentineledConnectionProvider;

import java.util.Set;

public class JedisSentineled extends UnifiedJedis {

public JedisSentineled(String masterName, final JedisClientConfig masterClientConfig,
Expand Down Expand Up @@ -40,6 +41,21 @@ public JedisSentineled(String masterName, final JedisClientConfig masterClientCo
masterClientConfig.getRedisProtocol());
}

public JedisSentineled(String masterName, final JedisClientConfig masterClientConfig,
final GenericObjectPoolConfig<Connection> poolConfig,
Set<HostAndPort> sentinels, final JedisClientConfig sentinelClientConfig, ReadFrom readFrom) {
super(new SentineledConnectionProvider(masterName, masterClientConfig, poolConfig, sentinels, sentinelClientConfig, readFrom),
masterClientConfig.getRedisProtocol());
}

public JedisSentineled(String masterName, final JedisClientConfig masterClientConfig,
final GenericObjectPoolConfig<Connection> poolConfig,
Set<HostAndPort> sentinels, final JedisClientConfig sentinelClientConfig, ReadFrom readFrom,
ReadOnlyPredicate readOnlyPredicate) {
super(new SentineledConnectionProvider(masterName, masterClientConfig, poolConfig, sentinels, sentinelClientConfig, readFrom, readOnlyPredicate),
masterClientConfig.getRedisProtocol());
}

@Experimental
public JedisSentineled(String masterName, final JedisClientConfig masterClientConfig, Cache clientSideCache,
final GenericObjectPoolConfig<Connection> poolConfig,
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/redis/clients/jedis/ReadFrom.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package redis.clients.jedis;

public enum ReadFrom {
// read from the upstream only.
UPSTREAM,
// read from the replica only.
REPLICA,
// read preferred from the upstream and fall back to a replica if the upstream is not available.
UPSTREAM_PREFERRED,
// read preferred from replica and fall back to upstream if no replica is not available.
REPLICA_PREFERRED
}
11 changes: 11 additions & 0 deletions src/main/java/redis/clients/jedis/ReadOnlyPredicate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package redis.clients.jedis;

@FunctionalInterface
public interface ReadOnlyPredicate {

/**
* @param command the input command.
* @return {@code true} if the input argument matches the predicate, otherwise {@code false}
*/
boolean isReadOnly(CommandArguments command);
}
16 changes: 16 additions & 0 deletions src/main/java/redis/clients/jedis/StaticReadOnlyPredicate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package redis.clients.jedis;

public class StaticReadOnlyPredicate implements ReadOnlyPredicate {

private static final StaticReadOnlyPredicate REGISTRY = new StaticReadOnlyPredicate();

private StaticReadOnlyPredicate(){}

public static StaticReadOnlyPredicate registry() {
return REGISTRY;
}

public boolean isReadOnly(CommandArguments command) {
return StaticCommandFlagsRegistry.registry().getFlags(command).contains(CommandFlagsRegistry.CommandFlag.READONLY);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package redis.clients.jedis.builders;

import java.util.Set;
import redis.clients.jedis.*;
import redis.clients.jedis.DefaultJedisClientConfig;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisClientConfig;
import redis.clients.jedis.ReadFrom;
import redis.clients.jedis.ReadOnlyPredicate;
import redis.clients.jedis.StaticReadOnlyPredicate;
import redis.clients.jedis.providers.ConnectionProvider;
import redis.clients.jedis.providers.SentineledConnectionProvider;

import java.util.Set;

/**
* Builder for creating JedisSentineled instances (Redis Sentinel connections).
* <p>
Expand All @@ -21,6 +27,10 @@ public abstract class SentinelClientBuilder<C>
private Set<HostAndPort> sentinels = null;
private JedisClientConfig sentinelClientConfig = null;

private ReadFrom readFrom = ReadFrom.UPSTREAM;

private ReadOnlyPredicate readOnlyPredicate = StaticReadOnlyPredicate.registry();

/**
* Sets the master name for the Redis Sentinel configuration.
* <p>
Expand All @@ -47,6 +57,33 @@ public SentinelClientBuilder<C> sentinels(Set<HostAndPort> sentinels) {
return this;
}

/**
* Sets the readFrom.
* <p>
* It is used to specify the policy preference of which nodes the client should read data from. It
* defines which type of node the client should prioritize reading data from when there are
* multiple Redis instances (such as master nodes and slave nodes) available in the Redis Sentinel
* environment.
* @param readFrom the read preferences
* @return this builder
*/
public SentinelClientBuilder<C> readForm(ReadFrom readFrom) {
this.readFrom = readFrom;
return this;
}

/**
* Sets the readOnlyPredicate.
* <p>
* Check a Redis command is a read request.
* @param readOnlyPredicate
* @return this builder
*/
public SentinelClientBuilder<C> readOnlyPredicate(ReadOnlyPredicate readOnlyPredicate) {
this.readOnlyPredicate = readOnlyPredicate;
return this;
}

/**
* Sets the client configuration for Sentinel connections.
* <p>
Expand All @@ -68,7 +105,8 @@ protected SentinelClientBuilder<C> self() {
@Override
protected ConnectionProvider createDefaultConnectionProvider() {
return new SentineledConnectionProvider(this.masterName, this.clientConfig, this.cache,
this.poolConfig, this.sentinels, this.sentinelClientConfig);
this.poolConfig, this.sentinels, this.sentinelClientConfig, this.readFrom,
this.readOnlyPredicate);
}

@Override
Expand Down
Loading