From d70cbb73f6064af723a26a89b04fe2b92e3cb1e3 Mon Sep 17 00:00:00 2001
From: Yeongjae Kim
Date: Sun, 11 Jan 2026 20:54:15 +0900
Subject: [PATCH 1/5] Add primary/replica terminology to core APIs #3463
---
src/main/java/io/lettuce/core/ReadFrom.java | 38 ++++-
src/main/java/io/lettuce/core/RedisURI.java | 142 +++++++++++++++---
.../core/models/role/RedisInstance.java | 40 +++++
.../core/models/role/RedisMasterInstance.java | 4 +-
.../models/role/RedisPrimaryInstance.java | 35 +++++
.../models/role/RedisReplicaInstance.java | 10 +-
.../models/role/RedisSentinelInstance.java | 4 +-
.../core/models/role/RedisSlaveInstance.java | 6 +-
8 files changed, 244 insertions(+), 35 deletions(-)
create mode 100644 src/main/java/io/lettuce/core/models/role/RedisPrimaryInstance.java
diff --git a/src/main/java/io/lettuce/core/ReadFrom.java b/src/main/java/io/lettuce/core/ReadFrom.java
index d4300ccefa..eaf99e3602 100644
--- a/src/main/java/io/lettuce/core/ReadFrom.java
+++ b/src/main/java/io/lettuce/core/ReadFrom.java
@@ -39,12 +39,18 @@ public abstract class ReadFrom {
/**
* Setting to read from the upstream only.
+ *
+ * @deprecated since 7.3, use {@link #PRIMARY}.
*/
+ @Deprecated
public static final ReadFrom MASTER = new ReadFromImpl.ReadFromUpstream();
/**
- * Setting to read preferred from the upstream and fall back to a replica if the master is not available.
+ * Setting to read preferred from the upstream and fall back to a replica if the primary is not available.
+ *
+ * @deprecated since 7.3, use {@link #PRIMARY_PREFERRED}.
*/
+ @Deprecated
public static final ReadFrom MASTER_PREFERRED = new ReadFromImpl.ReadFromUpstreamPreferred();
/**
@@ -61,6 +67,20 @@ public abstract class ReadFrom {
*/
public static final ReadFrom UPSTREAM_PREFERRED = new ReadFromImpl.ReadFromUpstreamPreferred();
+ /**
+ * Setting to read from the upstream only.
+ *
+ * @since 7.3
+ */
+ public static final ReadFrom PRIMARY = UPSTREAM;
+
+ /**
+ * Setting to read preferred from the upstream and fall back to a replica if the upstream is not available.
+ *
+ * @since 7.3
+ */
+ public static final ReadFrom PRIMARY_PREFERRED = UPSTREAM_PREFERRED;
+
/**
* Setting to read preferred from replica and fall back to upstream if no replica is available.
*
@@ -214,19 +234,27 @@ public static ReadFrom valueOf(String name) {
}
}
- if (name.equalsIgnoreCase("master")) {
+ if (name.equalsIgnoreCase("upstream")) {
return UPSTREAM;
}
- if (name.equalsIgnoreCase("masterPreferred")) {
+ if (name.equalsIgnoreCase("upstreamPreferred")) {
return UPSTREAM_PREFERRED;
}
- if (name.equalsIgnoreCase("upstream")) {
+ if (name.equalsIgnoreCase("primary")) {
+ return PRIMARY;
+ }
+
+ if (name.equalsIgnoreCase("primaryPreferred")) {
+ return PRIMARY_PREFERRED;
+ }
+
+ if (name.equalsIgnoreCase("master")) {
return UPSTREAM;
}
- if (name.equalsIgnoreCase("upstreamPreferred")) {
+ if (name.equalsIgnoreCase("masterPreferred")) {
return UPSTREAM_PREFERRED;
}
diff --git a/src/main/java/io/lettuce/core/RedisURI.java b/src/main/java/io/lettuce/core/RedisURI.java
index d5c6f09e38..e64dd693f9 100644
--- a/src/main/java/io/lettuce/core/RedisURI.java
+++ b/src/main/java/io/lettuce/core/RedisURI.java
@@ -60,8 +60,8 @@
*
* {@code RedisURI.Builder.redis("localhost", 6379).withPassword("password").withDatabase(1).build(); }
*
- * See {@link io.lettuce.core.RedisURI.Builder#redis(String)} and {@link io.lettuce.core.RedisURI.Builder#sentinel(String)} for
- * more options.
+ * See {@link io.lettuce.core.RedisURI.Builder#redis(String)} and
+ * {@link io.lettuce.core.RedisURI.Builder#sentinelPrimary(String, String)} for more options.
* Construct your own instance:
*
* {@code new RedisURI("localhost", 6379, Duration.ofSeconds(60));}
@@ -98,7 +98,7 @@
* redis-sentinel{@code ://}[[username{@code :}]password@]host1 [{@code :}
* port1][, host2 [{@code :}port2]][, hostN [{@code :}portN]][{@code /}
* database][{@code ?} [timeout=timeout[d|h|m|s|ms|us|ns]] [
- * &sentinelMasterId=sentinelMasterId] [&database=database] [&clientName=clientName]
+ * &sentinelPrimaryId=sentinelPrimaryId] [&database=database] [&clientName=clientName]
* [&libraryName=libraryName] [&libraryVersion=libraryVersion] [&verifyPeer=NONE|CA|FULL]]
*
*
@@ -184,8 +184,17 @@ public class RedisURI implements Serializable, ConnectionPoint {
public static final String PARAMETER_NAME_DATABASE_ALT = "db";
+ /**
+ * @deprecated since 7.3, use {@link #PARAMETER_NAME_SENTINEL_PRIMARY_ID}.
+ */
+ @Deprecated
public static final String PARAMETER_NAME_SENTINEL_MASTER_ID = "sentinelMasterId";
+ /**
+ * @since 7.3
+ */
+ public static final String PARAMETER_NAME_SENTINEL_PRIMARY_ID = "sentinelPrimaryId";
+
public static final String PARAMETER_NAME_CLIENT_NAME = "clientName";
public static final String PARAMETER_NAME_LIBRARY_NAME = "libraryName";
@@ -380,19 +389,43 @@ public void setHost(String host) {
}
/**
- * Returns the Sentinel Master Id.
+ * Returns the Sentinel primary id.
*
- * @return the Sentinel Master Id.
+ * @return the Sentinel primary id.
+ * @since 7.3
*/
+ public String getSentinelPrimaryId() {
+ return sentinelMasterId;
+ }
+
+ /**
+ * Sets the Sentinel primary id.
+ *
+ * @param sentinelPrimaryId the Sentinel primary id.
+ * @since 7.3
+ */
+ public void setSentinelPrimaryId(String sentinelPrimaryId) {
+ this.sentinelMasterId = sentinelPrimaryId;
+ }
+
+ /**
+ * Returns the Sentinel master id.
+ *
+ * @return the Sentinel master id.
+ * @deprecated since 7.3, use {@link #getSentinelPrimaryId()}.
+ */
+ @Deprecated
public String getSentinelMasterId() {
return sentinelMasterId;
}
/**
- * Sets the Sentinel Master Id.
+ * Sets the Sentinel master id.
*
- * @param sentinelMasterId the Sentinel Master Id.
+ * @param sentinelMasterId the Sentinel master id.
+ * @deprecated since 7.3, use {@link #setSentinelPrimaryId(String)}.
*/
+ @Deprecated
public void setSentinelMasterId(String sentinelMasterId) {
this.sentinelMasterId = sentinelMasterId;
}
@@ -520,7 +553,7 @@ public void setAuthentication(String username, CharSequence password) {
* provider no explicit {@link RedisCredentialsProvider} was configured.
*
* @return the {@link RedisCredentialsProvider} to use to authenticate Redis connections
- * @since 6.2
+ * @since 7.3
*/
public RedisCredentialsProvider getCredentialsProvider() {
return this.credentialsProvider;
@@ -531,7 +564,7 @@ public RedisCredentialsProvider getCredentialsProvider() {
* username/password.
*
* @param credentialsProvider the credentials provider to use when authenticating a Redis connection.
- * @since 6.2
+ * @since 7.3
*/
public void setCredentialsProvider(RedisCredentialsProvider credentialsProvider) {
@@ -897,6 +930,10 @@ private static RedisURI buildRedisUriFromUri(URI uri) {
parseVerifyPeer(builder, queryParam);
}
+ if (forStartWith.startsWith(PARAMETER_NAME_SENTINEL_PRIMARY_ID.toLowerCase() + "=")) {
+ parseSentinelPrimaryId(builder, queryParam);
+ }
+
if (forStartWith.startsWith(PARAMETER_NAME_SENTINEL_MASTER_ID.toLowerCase() + "=")) {
parseSentinelMasterId(builder, queryParam);
}
@@ -904,7 +941,7 @@ private static RedisURI buildRedisUriFromUri(URI uri) {
}
if (isSentinel(uri.getScheme())) {
- LettuceAssert.notEmpty(builder.sentinelMasterId, "URI must contain the sentinelMasterId");
+ LettuceAssert.notEmpty(builder.sentinelMasterId, "URI must contain the sentinelPrimaryId");
}
return builder.build();
@@ -995,7 +1032,7 @@ private String getQueryString() {
}
if (sentinelMasterId != null) {
- queryPairs.add(PARAMETER_NAME_SENTINEL_MASTER_ID + "=" + urlEncode(sentinelMasterId));
+ queryPairs.add(PARAMETER_NAME_SENTINEL_PRIMARY_ID + "=" + urlEncode(sentinelMasterId));
}
if (timeout.getSeconds() != DEFAULT_TIMEOUT) {
@@ -1190,11 +1227,15 @@ private static void parseVerifyPeer(Builder builder, String queryParam) {
}
}
+ private static void parseSentinelPrimaryId(Builder builder, String queryParam) {
+ parseSentinelMasterId(builder, queryParam);
+ }
+
private static void parseSentinelMasterId(Builder builder, String queryParam) {
String masterIdString = getValuePart(queryParam);
if (isNotEmpty(masterIdString)) {
- builder.withSentinelMasterId(masterIdString);
+ builder.withSentinelPrimaryId(masterIdString);
}
}
@@ -1295,7 +1336,7 @@ private static RedisURI.Builder configureSentinel(URI uri) {
LettuceAssert.notNull(builder, "Invalid URI, cannot get host part");
if (isNotEmpty(masterId)) {
- builder.withSentinelMasterId(masterId);
+ builder.withSentinelPrimaryId(masterId);
}
if (uri.getScheme().equals(URI_SCHEME_REDIS_SENTINEL_SECURE)) {
@@ -1416,13 +1457,59 @@ public static Builder sentinel(String host, int port) {
return builder.withSentinel(host, port);
}
+ /**
+ * Set Sentinel host and primary id. Creates a new builder.
+ *
+ * @param host the host name
+ * @param primaryId sentinel primary id
+ * @return new builder with Sentinel host/port.
+ * @since 7.3
+ */
+ public static Builder sentinelPrimary(String host, String primaryId) {
+ return sentinelPrimary(host, DEFAULT_SENTINEL_PORT, primaryId);
+ }
+
+ /**
+ * Set Sentinel host, port and primary id. Creates a new builder.
+ *
+ * @param host the host name
+ * @param port the port
+ * @param primaryId sentinel primary id
+ * @return new builder with Sentinel host/port.
+ * @since 7.3
+ */
+ public static Builder sentinelPrimary(String host, int port, String primaryId) {
+ return sentinelPrimary(host, port, primaryId, null);
+ }
+
+ /**
+ * Set Sentinel host, port, primary id and Sentinel authentication. Creates a new builder.
+ *
+ * @param host the host name
+ * @param port the port
+ * @param primaryId sentinel primary id
+ * @param password the Sentinel password (supported since Redis 5.0.1)
+ * @return new builder with Sentinel host/port.
+ * @since 7.3
+ */
+ public static Builder sentinelPrimary(String host, int port, String primaryId, CharSequence password) {
+
+ LettuceAssert.notEmpty(host, "Host must not be empty");
+ LettuceAssert.isTrue(isValidPort(port), () -> String.format("Port out of range: %s", port));
+
+ return password == null ? RedisURI.builder().withSentinelPrimaryId(primaryId).withSentinel(host, port)
+ : RedisURI.builder().withSentinelPrimaryId(primaryId).withSentinel(host, port, password);
+ }
+
/**
* Set Sentinel host and master id. Creates a new builder.
*
* @param host the host name
* @param masterId sentinel master id
* @return new builder with Sentinel host/port.
+ * @deprecated since 7.3, use {@link #sentinelPrimary(String, String)}.
*/
+ @Deprecated
public static Builder sentinel(String host, String masterId) {
return sentinel(host, DEFAULT_SENTINEL_PORT, masterId);
}
@@ -1434,7 +1521,9 @@ public static Builder sentinel(String host, String masterId) {
* @param port the port
* @param masterId sentinel master id
* @return new builder with Sentinel host/port.
+ * @deprecated since 7.3, use {@link #sentinelPrimary(String, int, String)}.
*/
+ @Deprecated
public static Builder sentinel(String host, int port, String masterId) {
return sentinel(host, port, masterId, null);
}
@@ -1447,7 +1536,9 @@ public static Builder sentinel(String host, int port, String masterId) {
* @param masterId sentinel master id
* @param password the Sentinel password (supported since Redis 5.0.1)
* @return new builder with Sentinel host/port.
+ * @deprecated since 7.3, use {@link #sentinelPrimary(String, int, String, CharSequence)}.
*/
+ @Deprecated
public static Builder sentinel(String host, int port, String masterId, CharSequence password) {
LettuceAssert.notEmpty(host, "Host must not be empty");
@@ -1762,7 +1853,7 @@ public Builder withAuthentication(String username, char[] password) {
* Configures authentication.
*
* @param credentialsProvider the credentials provider to use
- * @since 6.2
+ * @since 7.3
*/
public Builder withAuthentication(RedisCredentialsProvider credentialsProvider) {
this.credentialsProvider = credentialsProvider;
@@ -1815,19 +1906,32 @@ public Builder withTimeout(Duration timeout) {
}
/**
- * Configures a sentinel master Id.
+ * Configures a sentinel primary id.
*
- * @param sentinelMasterId sentinel master id, must not be empty or {@code null}
+ * @param sentinelPrimaryId sentinel primary id, must not be empty or {@code null}
* @return the builder
+ * @since 7.3
*/
- public Builder withSentinelMasterId(String sentinelMasterId) {
+ public Builder withSentinelPrimaryId(String sentinelPrimaryId) {
- LettuceAssert.notEmpty(sentinelMasterId, "Sentinel master id must not empty");
+ LettuceAssert.notEmpty(sentinelPrimaryId, "Sentinel primary id must not be empty");
- this.sentinelMasterId = sentinelMasterId;
+ this.sentinelMasterId = sentinelPrimaryId;
return this;
}
+ /**
+ * Configures a sentinel master id.
+ *
+ * @param sentinelMasterId sentinel master id, must not be empty or {@code null}
+ * @return the builder
+ * @deprecated since 7.3, use {@link #withSentinelPrimaryId(String)}.
+ */
+ @Deprecated
+ public Builder withSentinelMasterId(String sentinelMasterId) {
+ return withSentinelPrimaryId(sentinelMasterId);
+ }
+
/**
* Builds a new {@link RedisURI}.
*
diff --git a/src/main/java/io/lettuce/core/models/role/RedisInstance.java b/src/main/java/io/lettuce/core/models/role/RedisInstance.java
index 79c993bfca..0906d09c48 100644
--- a/src/main/java/io/lettuce/core/models/role/RedisInstance.java
+++ b/src/main/java/io/lettuce/core/models/role/RedisInstance.java
@@ -19,6 +19,7 @@ public interface RedisInstance {
*/
enum Role {
+ @Deprecated
MASTER {
@Override
@@ -31,6 +32,11 @@ public boolean isUpstream() {
return true;
}
+ @Override
+ public boolean isPrimary() {
+ return true;
+ }
+
},
@Deprecated
@@ -55,6 +61,30 @@ public boolean isUpstream() {
return true;
}
+ @Override
+ public boolean isPrimary() {
+ return true;
+ }
+
+ },
+
+ PRIMARY {
+
+ @Override
+ public boolean isMaster() {
+ return true;
+ }
+
+ @Override
+ public boolean isUpstream() {
+ return true;
+ }
+
+ @Override
+ public boolean isPrimary() {
+ return true;
+ }
+
},
REPLICA {
@@ -71,11 +101,21 @@ public boolean isReplica() {
/**
* @return {@code true} if the role indicates that the role is a replication source.
* @since 6.0
+ * @deprecated since 7.3, use {@link #isPrimary()} or {@link #isUpstream()}.
*/
+ @Deprecated
public boolean isMaster() {
return false;
}
+ /**
+ * @return {@code true} if the role indicates that the role is a primary replication source.
+ * @since 7.3
+ */
+ public boolean isPrimary() {
+ return false;
+ }
+
/**
* @return {@code true} if the role indicates that the role is a replication source.
* @since 6.1
diff --git a/src/main/java/io/lettuce/core/models/role/RedisMasterInstance.java b/src/main/java/io/lettuce/core/models/role/RedisMasterInstance.java
index 1ed7098732..7f231dec0c 100644
--- a/src/main/java/io/lettuce/core/models/role/RedisMasterInstance.java
+++ b/src/main/java/io/lettuce/core/models/role/RedisMasterInstance.java
@@ -3,12 +3,14 @@
import java.util.List;
/**
- * Represents a upstream (master) instance.
+ * Represents an upstream (primary) instance.
*
* @author Mark Paluch
* @since 3.0
+ * @deprecated since 7.3, use {@link RedisPrimaryInstance}.
*/
@SuppressWarnings("serial")
+@Deprecated
public class RedisMasterInstance extends RedisUpstreamInstance {
public RedisMasterInstance() {
diff --git a/src/main/java/io/lettuce/core/models/role/RedisPrimaryInstance.java b/src/main/java/io/lettuce/core/models/role/RedisPrimaryInstance.java
new file mode 100644
index 0000000000..04236fb315
--- /dev/null
+++ b/src/main/java/io/lettuce/core/models/role/RedisPrimaryInstance.java
@@ -0,0 +1,35 @@
+package io.lettuce.core.models.role;
+
+import java.util.List;
+
+/**
+ * Represents an upstream (primary) instance.
+ *
+ * @author
+ * @since 7.3
+ */
+@SuppressWarnings("serial")
+public class RedisPrimaryInstance extends RedisUpstreamInstance {
+
+ public RedisPrimaryInstance() {
+ }
+
+ /**
+ * Constructs a {@link RedisPrimaryInstance}
+ *
+ * @param replicationOffset the replication offset
+ * @param replicas list of replicas, must not be {@code null} but may be empty
+ */
+ public RedisPrimaryInstance(long replicationOffset, List replicas) {
+ super(replicationOffset, replicas);
+ }
+
+ /**
+ * @return always {@link io.lettuce.core.models.role.RedisInstance.Role#PRIMARY}
+ */
+ @Override
+ public Role getRole() {
+ return Role.PRIMARY;
+ }
+
+}
diff --git a/src/main/java/io/lettuce/core/models/role/RedisReplicaInstance.java b/src/main/java/io/lettuce/core/models/role/RedisReplicaInstance.java
index 19df1da8f4..f095edd5cd 100644
--- a/src/main/java/io/lettuce/core/models/role/RedisReplicaInstance.java
+++ b/src/main/java/io/lettuce/core/models/role/RedisReplicaInstance.java
@@ -23,7 +23,7 @@ public RedisReplicaInstance() {
/**
* Constructs a {@link RedisReplicaInstance}
*
- * @param upstream master for the replication, must not be {@code null}
+ * @param upstream primary for the replication, must not be {@code null}
* @param state replica state, must not be {@code null}
*/
RedisReplicaInstance(ReplicationPartner upstream, State state) {
@@ -87,17 +87,17 @@ public enum State {
*/
HANDSHAKE,
/**
- * the instance needs to connect to its master.
+ * the instance needs to connect to its primary.
*/
CONNECT,
/**
- * the replica-master connection is in progress.
+ * the replica-primary connection is in progress.
*/
CONNECTING,
/**
- * the master and replica are trying to perform the synchronization.
+ * the primary and replica are trying to perform the synchronization.
*/
SYNC,
@@ -111,7 +111,7 @@ public enum State {
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
- sb.append(" [master=").append(upstream);
+ sb.append(" [primary=").append(upstream);
sb.append(", state=").append(state);
sb.append(']');
return sb.toString();
diff --git a/src/main/java/io/lettuce/core/models/role/RedisSentinelInstance.java b/src/main/java/io/lettuce/core/models/role/RedisSentinelInstance.java
index 5af48d440a..df189829d1 100644
--- a/src/main/java/io/lettuce/core/models/role/RedisSentinelInstance.java
+++ b/src/main/java/io/lettuce/core/models/role/RedisSentinelInstance.java
@@ -23,7 +23,7 @@ public RedisSentinelInstance() {
/**
* Constructs a {@link RedisSentinelInstance}
*
- * @param monitoredMasters list of monitored masters, must not be {@code null} but may be empty
+ * @param monitoredMasters list of monitored primaries, must not be {@code null} but may be empty
*/
public RedisSentinelInstance(List monitoredMasters) {
LettuceAssert.notNull(monitoredMasters, "List of monitoredMasters must not be null");
@@ -41,7 +41,7 @@ public Role getRole() {
/**
*
- * @return List of monitored master names.
+ * @return List of monitored primary names.
*/
public List getMonitoredMasters() {
return monitoredMasters;
diff --git a/src/main/java/io/lettuce/core/models/role/RedisSlaveInstance.java b/src/main/java/io/lettuce/core/models/role/RedisSlaveInstance.java
index ee8a6b80ea..ec1069742b 100644
--- a/src/main/java/io/lettuce/core/models/role/RedisSlaveInstance.java
+++ b/src/main/java/io/lettuce/core/models/role/RedisSlaveInstance.java
@@ -21,7 +21,7 @@ public RedisSlaveInstance() {
/**
* Constructs a {@link RedisSlaveInstance}
*
- * @param master master for the replication, must not be {@code null}
+ * @param master primary for the replication, must not be {@code null}
* @param state replica state, must not be {@code null}
*/
RedisSlaveInstance(ReplicationPartner master, State state) {
@@ -38,14 +38,14 @@ public Role getRole() {
/**
*
- * @return the replication master.
+ * @return the replication primary.
*/
public ReplicationPartner getMaster() {
return getUpstream();
}
public void setMaster(ReplicationPartner master) {
- LettuceAssert.notNull(master, "Master must not be null");
+ LettuceAssert.notNull(master, "Primary must not be null");
setUpstream(master);
}
From afad5daa5a5147a02bc0e7a0a5c01e1fb6f8b4de Mon Sep 17 00:00:00 2001
From: Yeongjae Kim
Date: Sun, 11 Jan 2026 20:56:40 +0900
Subject: [PATCH 2/5] Add primary terminology to cluster and sentinel APIs
#3463
---
.../core/cluster/PartitionAccessor.java | 2 +-
.../PooledClusterConnectionProvider.java | 2 +-
.../RedisAdvancedClusterAsyncCommands.java | 12 +++-
.../sync/RedisAdvancedClusterCommands.java | 12 +++-
.../partitions/ClusterPartitionParser.java | 2 +-
.../cluster/models/partitions/Partitions.java | 2 +-
.../models/partitions/RedisClusterNode.java | 44 ++++++++++++--
.../models/slots/ClusterSlotRange.java | 24 ++++++--
.../models/slots/ClusterSlotsParser.java | 2 +-
.../RedisClusterPubSubAsyncCommands.java | 12 +++-
.../RedisClusterPubSubReactiveCommands.java | 12 +++-
.../api/sync/RedisClusterPubSubCommands.java | 12 +++-
.../api/async/RedisSentinelAsyncCommands.java | 60 +++++++++++++++----
.../RedisSentinelReactiveCommands.java | 60 +++++++++++++++----
.../api/sync/RedisSentinelCommands.java | 60 +++++++++++++++----
15 files changed, 265 insertions(+), 53 deletions(-)
diff --git a/src/main/java/io/lettuce/core/cluster/PartitionAccessor.java b/src/main/java/io/lettuce/core/cluster/PartitionAccessor.java
index 488309cde9..cb7698e359 100644
--- a/src/main/java/io/lettuce/core/cluster/PartitionAccessor.java
+++ b/src/main/java/io/lettuce/core/cluster/PartitionAccessor.java
@@ -27,7 +27,7 @@ List getUpstream() {
List getReadCandidates(RedisClusterNode upstream) {
return get(redisClusterNode -> redisClusterNode.getNodeId().equals(upstream.getNodeId())
|| (redisClusterNode.is(RedisClusterNode.NodeFlag.REPLICA)
- && upstream.getNodeId().equals(redisClusterNode.getSlaveOf())));
+ && upstream.getNodeId().equals(redisClusterNode.getReplicaOf())));
}
List get(Predicate test) {
diff --git a/src/main/java/io/lettuce/core/cluster/PooledClusterConnectionProvider.java b/src/main/java/io/lettuce/core/cluster/PooledClusterConnectionProvider.java
index e1f2bf56dd..edeb647762 100644
--- a/src/main/java/io/lettuce/core/cluster/PooledClusterConnectionProvider.java
+++ b/src/main/java/io/lettuce/core/cluster/PooledClusterConnectionProvider.java
@@ -428,7 +428,7 @@ private static boolean isReadCandidate(RedisClusterNode upstream, RedisClusterNo
}
// consider only replicas contain data from replication
- if (upstream.getNodeId().equals(partition.getSlaveOf()) && partition.getReplOffset() != 0) {
+ if (upstream.getNodeId().equals(partition.getReplicaOf()) && partition.getReplOffset() != 0) {
return true;
}
diff --git a/src/main/java/io/lettuce/core/cluster/api/async/RedisAdvancedClusterAsyncCommands.java b/src/main/java/io/lettuce/core/cluster/api/async/RedisAdvancedClusterAsyncCommands.java
index f89ba6b706..83de680180 100644
--- a/src/main/java/io/lettuce/core/cluster/api/async/RedisAdvancedClusterAsyncCommands.java
+++ b/src/main/java/io/lettuce/core/cluster/api/async/RedisAdvancedClusterAsyncCommands.java
@@ -84,7 +84,7 @@ public interface RedisAdvancedClusterAsyncCommands extends RedisClusterAsy
* Select all upstream nodes.
*
* @return API with asynchronous executed commands on a selection of upstream cluster nodes.
- * @deprecated since 6.0 in favor of {@link #upstream()}.
+ * @deprecated since 6.0 in favor of {@link #upstream()} (use {@link #primaries()} for primary terminology).
*/
default AsyncNodeSelection masters() {
return nodes(redisClusterNode -> redisClusterNode.is(RedisClusterNode.NodeFlag.UPSTREAM));
@@ -100,6 +100,16 @@ default AsyncNodeSelection upstream() {
return nodes(redisClusterNode -> redisClusterNode.is(RedisClusterNode.NodeFlag.UPSTREAM));
}
+ /**
+ * Select all primary nodes.
+ *
+ * @return API with asynchronous executed commands on a selection of primary cluster nodes.
+ * @since 7.3
+ */
+ default AsyncNodeSelection primaries() {
+ return upstream();
+ }
+
/**
* Select all replicas.
*
diff --git a/src/main/java/io/lettuce/core/cluster/api/sync/RedisAdvancedClusterCommands.java b/src/main/java/io/lettuce/core/cluster/api/sync/RedisAdvancedClusterCommands.java
index 28ecaf2986..a3f3fb1ca7 100644
--- a/src/main/java/io/lettuce/core/cluster/api/sync/RedisAdvancedClusterCommands.java
+++ b/src/main/java/io/lettuce/core/cluster/api/sync/RedisAdvancedClusterCommands.java
@@ -79,7 +79,7 @@ public interface RedisAdvancedClusterCommands extends RedisClusterCommands
* Select all upstream nodes.
*
* @return API with synchronous executed commands on a selection of upstream cluster nodes.
- * @deprecated since 6.0 in favor of {@link #upstream()}.
+ * @deprecated since 6.0 in favor of {@link #upstream()} (use {@link #primaries()} for primary terminology).
*/
@Deprecated
default NodeSelection masters() {
@@ -95,6 +95,16 @@ default NodeSelection upstream() {
return nodes(redisClusterNode -> redisClusterNode.is(RedisClusterNode.NodeFlag.UPSTREAM));
}
+ /**
+ * Select all primary nodes.
+ *
+ * @return API with synchronous executed commands on a selection of primary cluster nodes.
+ * @since 7.3
+ */
+ default NodeSelection primaries() {
+ return upstream();
+ }
+
/**
* Select all replicas.
*
diff --git a/src/main/java/io/lettuce/core/cluster/models/partitions/ClusterPartitionParser.java b/src/main/java/io/lettuce/core/cluster/models/partitions/ClusterPartitionParser.java
index af12099f52..bd85a70e83 100644
--- a/src/main/java/io/lettuce/core/cluster/models/partitions/ClusterPartitionParser.java
+++ b/src/main/java/io/lettuce/core/cluster/models/partitions/ClusterPartitionParser.java
@@ -115,7 +115,7 @@ private static void associateMasterWithReplicas(RedisClusterNode master, List
* Newly added or removed nodes to/from the Redis Cluster
* Changes in {@link RedisClusterNode#getSlots()} responsibility
- * Changes to the {@link RedisClusterNode#getSlaveOf() replication source} (the master of a replica)
+ * Changes to the {@link RedisClusterNode#getReplicaOf() replication source} (the primary of a replica)
* Changes to the {@link RedisClusterNode#getUri()} () connection point}
*
*
diff --git a/src/main/java/io/lettuce/core/cluster/models/partitions/RedisClusterNode.java b/src/main/java/io/lettuce/core/cluster/models/partitions/RedisClusterNode.java
index c17006f731..8f14042441 100644
--- a/src/main/java/io/lettuce/core/cluster/models/partitions/RedisClusterNode.java
+++ b/src/main/java/io/lettuce/core/cluster/models/partitions/RedisClusterNode.java
@@ -37,9 +37,10 @@
/**
* Representation of a Redis Cluster node. A {@link RedisClusterNode} is identified by its {@code nodeId}.
*
- * A {@link RedisClusterNode} can be a {@link #getRole() responsible master} or replica. Masters can be responsible for zero to
- * {@link io.lettuce.core.cluster.SlotHash#SLOT_COUNT 16384} slots. Each replica refers to exactly one {@link #getSlaveOf()
- * master}. Nodes can have different {@link io.lettuce.core.cluster.models.partitions.RedisClusterNode.NodeFlag flags} assigned.
+ * A {@link RedisClusterNode} can be a {@link #getRole() responsible primary} or replica. Primaries can be responsible for zero
+ * to {@link io.lettuce.core.cluster.SlotHash#SLOT_COUNT 16384} slots. Each replica refers to exactly one
+ * {@link #getReplicaOf()} primary upstream. Nodes can have different
+ * {@link io.lettuce.core.cluster.models.partitions.RedisClusterNode.NodeFlag flags} assigned.
*
* This class is mutable and not thread-safe if mutated by multiple threads concurrently.
*
@@ -206,6 +207,29 @@ public void setConnected(boolean connected) {
this.connected = connected;
}
+ /**
+ * @return the replication source, can be {@code null}
+ * @since 7.3
+ */
+ public String getReplicaOf() {
+ return slaveOf;
+ }
+
+ /**
+ * Sets the replication source.
+ *
+ * @param replicaOf the replication source, can be {@code null}
+ * @since 7.3
+ */
+ public void setReplicaOf(String replicaOf) {
+ this.slaveOf = replicaOf;
+ }
+
+ /**
+ * @return the replication source, can be {@code null}
+ * @deprecated since 7.3, use {@link #getReplicaOf()}.
+ */
+ @Deprecated
public String getSlaveOf() {
return slaveOf;
}
@@ -214,7 +238,9 @@ public String getSlaveOf() {
* Sets the replication source.
*
* @param slaveOf the replication source, can be {@code null}
+ * @deprecated since 7.3, use {@link #setReplicaOf(String)}.
*/
+ @Deprecated
public void setSlaveOf(String slaveOf) {
this.slaveOf = slaveOf;
}
@@ -407,8 +433,9 @@ public void setFlags(Set flags) {
*/
public boolean is(NodeFlag nodeFlag) {
- if (nodeFlag == NodeFlag.MASTER || nodeFlag == NodeFlag.UPSTREAM) {
- return getFlags().contains(NodeFlag.MASTER) || getFlags().contains(NodeFlag.UPSTREAM);
+ if (nodeFlag == NodeFlag.MASTER || nodeFlag == NodeFlag.UPSTREAM || nodeFlag == NodeFlag.PRIMARY) {
+ return getFlags().contains(NodeFlag.MASTER) || getFlags().contains(NodeFlag.UPSTREAM)
+ || getFlags().contains(NodeFlag.PRIMARY);
}
if (nodeFlag == NodeFlag.SLAVE || nodeFlag == NodeFlag.REPLICA) {
@@ -481,7 +508,7 @@ public String toString() {
sb.append(" [uri=").append(uri);
sb.append(", nodeId='").append(nodeId).append('\'');
sb.append(", connected=").append(connected);
- sb.append(", slaveOf='").append(slaveOf).append('\'');
+ sb.append(", replicaOf='").append(slaveOf).append('\'');
sb.append(", pingSentTimestamp=").append(pingSentTimestamp);
sb.append(", pongReceivedTimestamp=").append(pongReceivedTimestamp);
sb.append(", configEpoch=").append(configEpoch);
@@ -509,6 +536,11 @@ public enum NodeFlag {
REPLICA, //
+ /**
+ * Synonym for {@link #UPSTREAM}.
+ */
+ PRIMARY, //
+
/**
* Synonym for {@link #UPSTREAM}.
*/
diff --git a/src/main/java/io/lettuce/core/cluster/models/slots/ClusterSlotRange.java b/src/main/java/io/lettuce/core/cluster/models/slots/ClusterSlotRange.java
index 74e0dad436..56334c03cc 100644
--- a/src/main/java/io/lettuce/core/cluster/models/slots/ClusterSlotRange.java
+++ b/src/main/java/io/lettuce/core/cluster/models/slots/ClusterSlotRange.java
@@ -12,7 +12,7 @@
import io.lettuce.core.internal.LettuceAssert;
/**
- * Represents a range of slots together with its master and replicas.
+ * Represents a range of slots together with its primary and replicas.
*
* @author Mark Paluch
* @since 3.0
@@ -36,7 +36,7 @@ public ClusterSlotRange() {
*
* @param from from slot
* @param to to slot
- * @param upstream master for the slots, may be {@code null}
+ * @param upstream primary for the slots, may be {@code null}
* @param replicaNodes list of replicas must not be {@code null} but may be empty
*/
public ClusterSlotRange(int from, int to, RedisClusterNode upstream, List replicaNodes) {
@@ -55,7 +55,7 @@ private RedisClusterNode toRedisClusterNode(HostAndPort hostAndPort, String slav
int port = hostAndPort.hasPort() ? hostAndPort.getPort() : RedisURI.DEFAULT_REDIS_PORT;
RedisClusterNode redisClusterNode = new RedisClusterNode();
redisClusterNode.setUri(RedisURI.create(hostAndPort.getHostText(), port));
- redisClusterNode.setSlaveOf(slaveOf);
+ redisClusterNode.setReplicaOf(slaveOf);
redisClusterNode.setFlags(flags);
return redisClusterNode;
}
@@ -81,10 +81,26 @@ public RedisClusterNode getUpstream() {
return upstream;
}
+ /**
+ * @return the primary for the slots, may be {@code null}
+ * @since 7.3
+ */
+ public RedisClusterNode getPrimary() {
+ return upstream;
+ }
+
public void setUpstream(RedisClusterNode upstream) {
this.upstream = upstream;
}
+ /**
+ * @param primary the primary for the slots, may be {@code null}
+ * @since 7.3
+ */
+ public void setPrimary(RedisClusterNode primary) {
+ this.upstream = primary;
+ }
+
@Deprecated
public List getSlaveNodes() {
return replicaNodes;
@@ -117,7 +133,7 @@ public String toString() {
sb.append(getClass().getSimpleName());
sb.append(" [from=").append(from);
sb.append(", to=").append(to);
- sb.append(", masterNode=").append(upstream);
+ sb.append(", primaryNode=").append(upstream);
sb.append(", replicaNodes=").append(replicaNodes);
sb.append(']');
return sb.toString();
diff --git a/src/main/java/io/lettuce/core/cluster/models/slots/ClusterSlotsParser.java b/src/main/java/io/lettuce/core/cluster/models/slots/ClusterSlotsParser.java
index 6583476f56..bff2ee56e1 100644
--- a/src/main/java/io/lettuce/core/cluster/models/slots/ClusterSlotsParser.java
+++ b/src/main/java/io/lettuce/core/cluster/models/slots/ClusterSlotsParser.java
@@ -87,7 +87,7 @@ private static ClusterSlotRange parseRange(List> range, Map extends RedisPubSubAsyncC
* Select all upstream nodes.
*
* @return API with asynchronous executed commands on a selection of upstream cluster nodes.
- * @deprecated since 6.0 in favor of {@link #upstream()}.
+ * @deprecated since 6.0 in favor of {@link #upstream()} (use {@link #primaries()} for primary terminology).
*/
@Deprecated
default PubSubAsyncNodeSelection masters() {
@@ -42,6 +42,16 @@ default PubSubAsyncNodeSelection upstream() {
return nodes(redisClusterNode -> redisClusterNode.is(RedisClusterNode.NodeFlag.UPSTREAM));
}
+ /**
+ * Select all primary nodes.
+ *
+ * @return API with asynchronous executed commands on a selection of primary cluster nodes.
+ * @since 7.3
+ */
+ default PubSubAsyncNodeSelection primaries() {
+ return upstream();
+ }
+
/**
* Select all replicas.
*
diff --git a/src/main/java/io/lettuce/core/cluster/pubsub/api/reactive/RedisClusterPubSubReactiveCommands.java b/src/main/java/io/lettuce/core/cluster/pubsub/api/reactive/RedisClusterPubSubReactiveCommands.java
index a8f6a21201..4a675428d1 100644
--- a/src/main/java/io/lettuce/core/cluster/pubsub/api/reactive/RedisClusterPubSubReactiveCommands.java
+++ b/src/main/java/io/lettuce/core/cluster/pubsub/api/reactive/RedisClusterPubSubReactiveCommands.java
@@ -28,7 +28,7 @@ public interface RedisClusterPubSubReactiveCommands extends RedisPubSubRea
* Select all upstream nodes.
*
* @return API with reactive executed commands on a selection of upstream cluster nodes.
- * @deprecated since 6.0 in favor of {@link #upstream()}.
+ * @deprecated since 6.0 in favor of {@link #upstream()} (use {@link #primaries()} for primary terminology).
*/
@Deprecated
default PubSubReactiveNodeSelection masters() {
@@ -44,6 +44,16 @@ default PubSubReactiveNodeSelection upstream() {
return nodes(redisClusterNode -> redisClusterNode.is(RedisClusterNode.NodeFlag.UPSTREAM));
}
+ /**
+ * Select all primary nodes.
+ *
+ * @return API with asynchronous executed commands on a selection of primary cluster nodes.
+ * @since 7.3
+ */
+ default PubSubReactiveNodeSelection primaries() {
+ return upstream();
+ }
+
/**
* Select all replicas.
*
diff --git a/src/main/java/io/lettuce/core/cluster/pubsub/api/sync/RedisClusterPubSubCommands.java b/src/main/java/io/lettuce/core/cluster/pubsub/api/sync/RedisClusterPubSubCommands.java
index 4674c524fb..1125c8bc6f 100644
--- a/src/main/java/io/lettuce/core/cluster/pubsub/api/sync/RedisClusterPubSubCommands.java
+++ b/src/main/java/io/lettuce/core/cluster/pubsub/api/sync/RedisClusterPubSubCommands.java
@@ -26,7 +26,7 @@ public interface RedisClusterPubSubCommands extends RedisPubSubCommands masters() {
@@ -43,6 +43,16 @@ default PubSubNodeSelection upstream() {
return nodes(redisClusterNode -> redisClusterNode.is(RedisClusterNode.NodeFlag.UPSTREAM));
}
+ /**
+ * Select all primary nodes.
+ *
+ * @return API with asynchronous executed commands on a selection of primary cluster nodes.
+ * @since 7.3
+ */
+ default PubSubNodeSelection primaries() {
+ return upstream();
+ }
+
/**
* Select all replicas.
*
diff --git a/src/main/java/io/lettuce/core/sentinel/api/async/RedisSentinelAsyncCommands.java b/src/main/java/io/lettuce/core/sentinel/api/async/RedisSentinelAsyncCommands.java
index 503306341b..f9f9b86d43 100644
--- a/src/main/java/io/lettuce/core/sentinel/api/async/RedisSentinelAsyncCommands.java
+++ b/src/main/java/io/lettuce/core/sentinel/api/async/RedisSentinelAsyncCommands.java
@@ -43,40 +43,78 @@
public interface RedisSentinelAsyncCommands {
/**
- * Return the ip and port number of the master with that name.
+ * Return the ip and port number of the primary with that name.
*
* @param key the key.
* @return SocketAddress.
+ * @since 7.3
*/
+ default RedisFuture getPrimaryAddrByName(K key) {
+ return getMasterAddrByName(key);
+ }
+
+ /**
+ * Return the ip and port number of the primary with that name.
+ *
+ * @param key the key.
+ * @return SocketAddress.
+ * @deprecated since 7.3, use {@link #getPrimaryAddrByName(Object)}.
+ */
+ @Deprecated
RedisFuture getMasterAddrByName(K key);
/**
- * Enumerates all the monitored masters and their states.
+ * Enumerates all the monitored primaries and their states.
+ *
+ * @return Map<K, V>>.
+ * @since 7.3
+ */
+ default RedisFuture>> primaries() {
+ return masters();
+ }
+
+ /**
+ * Enumerates all the monitored primaries and their states.
*
* @return Map<K, V>>.
+ * @deprecated since 7.3, use {@link #primaries()}.
*/
+ @Deprecated
RedisFuture>> masters();
/**
- * Show the state and info of the specified master.
+ * Show the state and info of the specified primary.
+ *
+ * @param key the key.
+ * @return Map<K, V>.
+ * @since 7.3
+ */
+ default RedisFuture
* Topology Discovery
*
- * Master-Replica topologies are either static or semi-static. Redis Standalone instances with attached replicas provide no
+ * Primary-Replica topologies are either static or semi-static. Redis Standalone instances with attached replicas provide no
* failover/HA mechanism. Redis Sentinel managed instances are controlled by Redis Sentinel and allow failover (which include
- * master promotion). The {@link MasterReplica} API supports both mechanisms. The topology is provided by a
+ * primary promotion). The {@link MasterReplica} API supports both mechanisms. The topology is provided by a
* {@link TopologyProvider}:
*
*
* - {@link ReplicaTopologyProvider}: Dynamic topology lookup using the {@code INFO REPLICATION} output. Replicas are listed
- * as {@code replicaN=...} entries. The initial connection can either point to a master or a replica and the topology provider
- * will discover nodes. The connection needs to be re-established outside of lettuce in a case of Master/Replica failover or
+ * as {@code replicaN=...} entries. The initial connection can either point to a primary or a replica and the topology provider
+ * will discover nodes. The connection needs to be re-established outside of lettuce in a case of Primary/Replica failover or
* topology changes.
* - {@link StaticMasterReplicaTopologyProvider}: Topology is defined by the list of {@link RedisURI URIs} and the
- * {@code ROLE} output. MasterReplica uses only the supplied nodes and won't discover additional nodes in the setup. The
- * connection needs to be re-established outside of lettuce in a case of Master/Replica failover or topology changes.
+ * {@code ROLE} output. This API uses only the supplied nodes and won't discover additional nodes in the setup. The connection
+ * needs to be re-established outside of lettuce in a case of Primary/Replica failover or topology changes.
* {@link SentinelTopologyProvider}: Dynamic topology lookup using the Redis Sentinel API. In particular,
- * {@code SENTINEL MASTER} and {@code SENTINEL SLAVES} output. Master/Replica failover is handled by lettuce.
+ * {@code SENTINEL MASTER} and {@code SENTINEL SLAVES} output. Primary/Replica failover is handled by lettuce.
*
*
* Topology Updates
*
- * - Standalone Master/Replica: Performs a one-time topology lookup which remains static afterward
+ * - Standalone Primary/Replica: Performs a one-time topology lookup which remains static afterward
* - Redis Sentinel: Subscribes to all Sentinels and listens for Pub/Sub messages to trigger topology refreshing
*
*
- * Connection Fault-Tolerance
Connecting to Master/Replica bears the possibility that individual nodes are not
+ * Connection Fault-Tolerance
Connecting to Primary/Replica bears the possibility that individual nodes are not
* reachable. {@link MasterReplica} can still connect to a partially-available set of nodes.
*
*
- * - Redis Sentinel: At least one Sentinel must be reachable, the masterId must be registered and at least one host must be
- * available (master or replica). Allows for runtime-recovery based on Sentinel Events.
+ * - Redis Sentinel: At least one Sentinel must be reachable, the primaryId must be registered and at least one host must be
+ * available (primary or replica). Allows for runtime-recovery based on Sentinel Events.
* - Static Setup (auto-discovery): The initial endpoint must be reachable. No recovery/reconfiguration during runtime.
* - Static Setup (provided hosts): All endpoints must be reachable. No recovery/reconfiguration during runtime.
*
*
* @author Mark Paluch
* @since 5.2
+ * @deprecated since 7.3, use {@link io.lettuce.core.primaryreplica.PrimaryReplica}.
*/
+@Deprecated
public class MasterReplica {
/**
- * Open a new connection to a Redis Master-Replica server/servers using the supplied {@link RedisURI} and the supplied
+ * Open a new connection to a Redis Primary-Replica server/servers using the supplied {@link RedisURI} and the supplied
* {@link RedisCodec codec} to encode/decode keys.
*
- * This {@link MasterReplica} performs auto-discovery of nodes using either Redis Sentinel or Master/Replica. A
- * {@link RedisURI} can point to either a master or a replica host.
+ * This {@link MasterReplica} performs auto-discovery of nodes using either Redis Sentinel or Primary/Replica. A
+ * {@link RedisURI} can point to either a primary or a replica host.
*
*
* @param redisClient the Redis client.
@@ -99,11 +101,11 @@ public static StatefulRedisMasterReplicaConnection connect(RedisCli
}
/**
- * Open asynchronously a new connection to a Redis Master-Replica server/servers using the supplied {@link RedisURI} and the
- * supplied {@link RedisCodec codec} to encode/decode keys.
+ * Open asynchronously a new connection to a Redis Primary-Replica server/servers using the supplied {@link RedisURI} and
+ * the supplied {@link RedisCodec codec} to encode/decode keys.
*
- * This {@link MasterReplica} performs auto-discovery of nodes using either Redis Sentinel or Master/Replica. A
- * {@link RedisURI} can point to either a master or a replica host.
+ * This {@link MasterReplica} performs auto-discovery of nodes using either Redis Sentinel or Primary/Replica. A
+ * {@link RedisURI} can point to either a primary or a replica host.
*
*
* @param redisClient the Redis client.
@@ -134,11 +136,11 @@ private static CompletableFuture
- * This {@link MasterReplica} performs auto-discovery of nodes if the URI is a Redis Sentinel URI. Master/Replica URIs will
- * be treated as static topology and no additional hosts are discovered in such case. Redis Standalone Master/Replica will
+ * This {@link MasterReplica} performs auto-discovery of nodes if the URI is a Redis Sentinel URI. Primary/Replica URIs will
+ * be treated as static topology and no additional hosts are discovered in such case. Redis Standalone Primary/Replica will
* discover the roles of the supplied {@link RedisURI URIs} and issue commands to the appropriate node.
*
*
@@ -161,11 +163,11 @@ public static StatefulRedisMasterReplicaConnection connect(RedisCli
}
/**
- * Open asynchronously a new connection to a Redis Master-Replica server/servers using the supplied {@link RedisURI} and the
- * supplied {@link RedisCodec codec} to encode/decode keys.
+ * Open asynchronously a new connection to a Redis Primary-Replica server/servers using the supplied {@link RedisURI} and
+ * the supplied {@link RedisCodec codec} to encode/decode keys.
*
- * This {@link MasterReplica} performs auto-discovery of nodes if the URI is a Redis Sentinel URI. Master/Replica URIs will
- * be treated as static topology and no additional hosts are discovered in such case. Redis Standalone Master/Replica will
+ * This {@link MasterReplica} performs auto-discovery of nodes if the URI is a Redis Sentinel URI. Primary/Replica URIs will
+ * be treated as static topology and no additional hosts are discovered in such case. Redis Standalone Primary/Replica will
* discover the roles of the supplied {@link RedisURI URIs} and issue commands to the appropriate node.
*
*
diff --git a/src/main/java/io/lettuce/core/masterreplica/ReplicaTopologyProvider.java b/src/main/java/io/lettuce/core/masterreplica/ReplicaTopologyProvider.java
index c93ce8a138..b555d91e2b 100644
--- a/src/main/java/io/lettuce/core/masterreplica/ReplicaTopologyProvider.java
+++ b/src/main/java/io/lettuce/core/masterreplica/ReplicaTopologyProvider.java
@@ -182,7 +182,7 @@ private RedisNodeDescription getMasterFromInfo(String info) {
boolean foundPort = masterPortMatcher.find();
if (!foundHost || !foundPort) {
- throw new IllegalStateException("Cannot resolve master from info " + info);
+ throw new IllegalStateException("Cannot resolve primary from info " + info);
}
String host = masterHostMatcher.group(1);
diff --git a/src/main/java/io/lettuce/core/masterreplica/SentinelTopologyProvider.java b/src/main/java/io/lettuce/core/masterreplica/SentinelTopologyProvider.java
index e00d340080..13960d220d 100644
--- a/src/main/java/io/lettuce/core/masterreplica/SentinelTopologyProvider.java
+++ b/src/main/java/io/lettuce/core/masterreplica/SentinelTopologyProvider.java
@@ -62,7 +62,7 @@ public SentinelTopologyProvider(String masterId, RedisClient redisClient, RedisU
@Override
public List getNodes() {
- logger.debug("lookup topology for masterId {}", masterId);
+ logger.debug("lookup topology for primaryId {}", masterId);
try {
return getNodesAsync().get(timeout.toMillis(), TimeUnit.MILLISECONDS);
@@ -74,7 +74,7 @@ public List getNodes() {
@Override
public CompletableFuture> getNodesAsync() {
- logger.debug("lookup topology for masterId {}", masterId);
+ logger.debug("lookup topology for primaryId {}", masterId);
Mono> connect = Mono
.fromFuture(redisClient.connectSentinelAsync(StringCodec.UTF8, sentinelUri));
diff --git a/src/main/java/io/lettuce/core/masterreplica/StatefulRedisMasterReplicaConnection.java b/src/main/java/io/lettuce/core/masterreplica/StatefulRedisMasterReplicaConnection.java
index ce5a9edbd0..5260a42aa5 100644
--- a/src/main/java/io/lettuce/core/masterreplica/StatefulRedisMasterReplicaConnection.java
+++ b/src/main/java/io/lettuce/core/masterreplica/StatefulRedisMasterReplicaConnection.java
@@ -1,7 +1,7 @@
package io.lettuce.core.masterreplica;
import io.lettuce.core.ReadFrom;
-import io.lettuce.core.api.StatefulRedisConnection;
+import io.lettuce.core.primaryreplica.StatefulRedisPrimaryReplicaConnection;
/**
* Redis Master-Replica connection. The connection allows replica reads by setting {@link ReadFrom}.
@@ -10,22 +10,28 @@
* @param Value type.
* @author Mark Paluch
* @since 4.1
+ * @deprecated since 7.3, use {@link io.lettuce.core.primaryreplica.StatefulRedisPrimaryReplicaConnection}.
*/
-public interface StatefulRedisMasterReplicaConnection extends StatefulRedisConnection {
+@Deprecated
+public interface StatefulRedisMasterReplicaConnection extends StatefulRedisPrimaryReplicaConnection {
/**
* Set from which nodes data is read. The setting is used as default for read operations on this connection. See the
* documentation for {@link ReadFrom} for more information.
*
* @param readFrom the read from setting, must not be {@code null}
+ * @deprecated since 7.3, use {@link StatefulRedisPrimaryReplicaConnection#setReadFrom(ReadFrom)}.
*/
+ @Deprecated
void setReadFrom(ReadFrom readFrom);
/**
* Gets the {@link ReadFrom} setting for this connection. Defaults to {@link ReadFrom#UPSTREAM} if not set.
*
* @return the read from setting
+ * @deprecated since 7.3, use {@link StatefulRedisPrimaryReplicaConnection#getReadFrom()}.
*/
+ @Deprecated
ReadFrom getReadFrom();
}
diff --git a/src/main/java/io/lettuce/core/masterreplica/package-info.java b/src/main/java/io/lettuce/core/masterreplica/package-info.java
index a4cf1cbea0..3721dd6217 100644
--- a/src/main/java/io/lettuce/core/masterreplica/package-info.java
+++ b/src/main/java/io/lettuce/core/masterreplica/package-info.java
@@ -1,6 +1,6 @@
/**
- * Client support for Redis Master/Replica setups. {@link io.lettuce.core.masterreplica.MasterReplica} supports self-managed,
- * Redis Sentinel-managed, AWS ElastiCache and Azure Redis managed Master/Replica setups.
+ * Client support for Redis Primary/Replica setups. {@link io.lettuce.core.primaryreplica.PrimaryReplica} supports self-managed,
+ * Redis Sentinel-managed, AWS ElastiCache and Azure Redis managed Primary/Replica setups.
*
* Connections can be obtained by providing the {@link io.lettuce.core.RedisClient}, a {@link io.lettuce.core.RedisURI} and a
* {@link io.lettuce.core.codec.RedisCodec}.
@@ -8,7 +8,7 @@
*
*
* RedisClient client = RedisClient.create();
- * StatefulRedisMasterReplicaConnection connection = MasterReplica.connect(client,
+ * StatefulRedisPrimaryReplicaConnection connection = PrimaryReplica.connect(client,
* RedisURI.create("redis://localhost"), StringCodec.UTF8);
* // ...
*
diff --git a/src/main/java/io/lettuce/core/primaryreplica/PrimaryReplica.java b/src/main/java/io/lettuce/core/primaryreplica/PrimaryReplica.java
new file mode 100644
index 0000000000..f20e6fdad7
--- /dev/null
+++ b/src/main/java/io/lettuce/core/primaryreplica/PrimaryReplica.java
@@ -0,0 +1,108 @@
+package io.lettuce.core.primaryreplica;
+
+import java.util.concurrent.CompletableFuture;
+
+import io.lettuce.core.RedisClient;
+import io.lettuce.core.RedisURI;
+import io.lettuce.core.codec.RedisCodec;
+import io.lettuce.core.masterreplica.MasterReplica;
+
+/**
+ * Primary-Replica connection API.
+ *
+ * This API allows connections to Redis Primary/Replica setups which run either in a static Primary/Replica setup or are managed
+ * by Redis Sentinel. Primary-Replica connections can discover topologies and select a source for read operations using
+ * {@link io.lettuce.core.ReadFrom}.
+ *
+ *
+ * @author Mark Paluch
+ * @since 7.3
+ */
+@SuppressWarnings("deprecation")
+public class PrimaryReplica {
+
+ /**
+ * Open a new connection to a Redis Primary-Replica server/servers using the supplied {@link RedisURI} and the supplied
+ * {@link RedisCodec codec} to encode/decode keys.
+ *
+ * This {@link PrimaryReplica} performs auto-discovery of nodes using either Redis Sentinel or Primary/Replica. A
+ * {@link RedisURI} can point to either a primary or a replica host.
+ *
+ *
+ * @param redisClient the Redis client.
+ * @param codec Use this codec to encode/decode keys and values, must not be {@code null}.
+ * @param redisURI the Redis server to connect to, must not be {@code null}.
+ * @param Key type.
+ * @param Value type.
+ * @return a new connection.
+ */
+ public static StatefulRedisPrimaryReplicaConnection connect(RedisClient redisClient, RedisCodec codec,
+ RedisURI redisURI) {
+ return MasterReplica.connect(redisClient, codec, redisURI);
+ }
+
+ /**
+ * Open asynchronously a new connection to a Redis Primary-Replica server/servers using the supplied {@link RedisURI} and
+ * the supplied {@link RedisCodec codec} to encode/decode keys.
+ *
+ * This {@link PrimaryReplica} performs auto-discovery of nodes using either Redis Sentinel or Primary/Replica. A
+ * {@link RedisURI} can point to either a primary or a replica host.
+ *
+ *
+ * @param redisClient the Redis client.
+ * @param codec Use this codec to encode/decode keys and values, must not be {@code null}.
+ * @param redisURI the Redis server to connect to, must not be {@code null}.
+ * @param Key type.
+ * @param Value type.
+ * @return {@link CompletableFuture} that is notified once the connect is finished.
+ */
+ public static CompletableFuture> connectAsync(RedisClient redisClient,
+ RedisCodec codec, RedisURI redisURI) {
+ return MasterReplica.connectAsync(redisClient, codec, redisURI)
+ .thenApply(connection -> (StatefulRedisPrimaryReplicaConnection) connection);
+ }
+
+ /**
+ * Open a new connection to a Redis Primary-Replica server/servers using the supplied {@link RedisURI} and the supplied
+ * {@link RedisCodec codec} to encode/decode keys.
+ *
+ * This {@link PrimaryReplica} performs auto-discovery of nodes if the URI is a Redis Sentinel URI. Primary/Replica URIs
+ * will be treated as static topology and no additional hosts are discovered in such case. Redis Standalone Primary/Replica
+ * will discover the roles of the supplied {@link RedisURI URIs} and issue commands to the appropriate node.
+ *
+ *
+ * @param redisClient the Redis client.
+ * @param codec Use this codec to encode/decode keys and values, must not be {@code null}.
+ * @param redisURIs the Redis server(s) to connect to, must not be {@code null}.
+ * @param Key type.
+ * @param Value type.
+ * @return a new connection.
+ */
+ public static StatefulRedisPrimaryReplicaConnection connect(RedisClient redisClient, RedisCodec codec,
+ Iterable redisURIs) {
+ return MasterReplica.connect(redisClient, codec, redisURIs);
+ }
+
+ /**
+ * Open asynchronously a new connection to a Redis Primary-Replica server/servers using the supplied {@link RedisURI} and
+ * the supplied {@link RedisCodec codec} to encode/decode keys.
+ *
+ * This {@link PrimaryReplica} performs auto-discovery of nodes if the URI is a Redis Sentinel URI. Primary/Replica URIs
+ * will be treated as static topology and no additional hosts are discovered in such case. Redis Standalone Primary/Replica
+ * will discover the roles of the supplied {@link RedisURI URIs} and issue commands to the appropriate node.
+ *
+ *
+ * @param redisClient the Redis client.
+ * @param codec Use this codec to encode/decode keys and values, must not be {@code null}.
+ * @param redisURIs the Redis server(s) to connect to, must not be {@code null}.
+ * @param Key type.
+ * @param Value type.
+ * @return {@link CompletableFuture} that is notified once the connect is finished.
+ */
+ public static CompletableFuture> connectAsync(RedisClient redisClient,
+ RedisCodec codec, Iterable redisURIs) {
+ return MasterReplica.connectAsync(redisClient, codec, redisURIs)
+ .thenApply(connection -> (StatefulRedisPrimaryReplicaConnection) connection);
+ }
+
+}
diff --git a/src/main/java/io/lettuce/core/primaryreplica/StatefulRedisPrimaryReplicaConnection.java b/src/main/java/io/lettuce/core/primaryreplica/StatefulRedisPrimaryReplicaConnection.java
new file mode 100644
index 0000000000..9fcd27c839
--- /dev/null
+++ b/src/main/java/io/lettuce/core/primaryreplica/StatefulRedisPrimaryReplicaConnection.java
@@ -0,0 +1,31 @@
+package io.lettuce.core.primaryreplica;
+
+import io.lettuce.core.ReadFrom;
+import io.lettuce.core.api.StatefulRedisConnection;
+
+/**
+ * Redis Primary-Replica connection. The connection allows replica reads by setting {@link ReadFrom}.
+ *
+ * @param Key type.
+ * @param Value type.
+ * @author
+ * @since 7.3
+ */
+public interface StatefulRedisPrimaryReplicaConnection extends StatefulRedisConnection {
+
+ /**
+ * Set from which nodes data is read. The setting is used as default for read operations on this connection. See the
+ * documentation for {@link ReadFrom} for more information.
+ *
+ * @param readFrom the read from setting, must not be {@code null}
+ */
+ void setReadFrom(ReadFrom readFrom);
+
+ /**
+ * Gets the {@link ReadFrom} setting for this connection. Defaults to {@link ReadFrom#PRIMARY} if not set.
+ *
+ * @return the read from setting
+ */
+ ReadFrom getReadFrom();
+
+}
diff --git a/src/main/resources/META-INF/native-image/io.lettuce/lettuce-core/proxy-config.json b/src/main/resources/META-INF/native-image/io.lettuce/lettuce-core/proxy-config.json
index 8d6f4cfd49..f4156790a2 100644
--- a/src/main/resources/META-INF/native-image/io.lettuce/lettuce-core/proxy-config.json
+++ b/src/main/resources/META-INF/native-image/io.lettuce/lettuce-core/proxy-config.json
@@ -44,6 +44,10 @@
"io.lettuce.core.support.ConnectionWrapping$HasTargetConnection",
"io.lettuce.core.masterreplica.StatefulRedisMasterReplicaConnection"
],
+ [
+ "io.lettuce.core.support.ConnectionWrapping$HasTargetConnection",
+ "io.lettuce.core.primaryreplica.StatefulRedisPrimaryReplicaConnection"
+ ],
[
"io.lettuce.core.support.ConnectionWrapping$HasTargetConnection",
"io.lettuce.core.api.StatefulRedisConnection"
From 41030f177e7d47a07599e8a6efc48a4dfc6389f9 Mon Sep 17 00:00:00 2001
From: Yeongjae Kim
Date: Sun, 11 Jan 2026 20:59:20 +0900
Subject: [PATCH 4/5] Update documentation and examples for primary/replica
terminology #3463
---
docs/advanced-usage.md | 11 +-
docs/ha-sharding.md | 195 +++++++++---------
docs/new-features.md | 5 +-
docs/redis-command-interfaces.md | 3 +-
docs/user-guide/async-api.md | 8 +-
docs/user-guide/pubsub.md | 8 +-
.../io/lettuce/core/RedisURIUnitTests.java | 5 +-
...tToMasterSlaveUsingElastiCacheCluster.java | 25 +--
...onnectToMasterSlaveUsingRedisSentinel.java | 21 +-
...PrimaryReplicaUsingElastiCacheCluster.java | 37 ++++
...ectToPrimaryReplicaUsingRedisSentinel.java | 30 +++
.../ConnectToRedisUsingRedisSentinel.java | 4 +-
src/test/resources/spring-test.xml | 6 +-
13 files changed, 194 insertions(+), 164 deletions(-)
create mode 100644 src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingElastiCacheCluster.java
create mode 100644 src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingRedisSentinel.java
diff --git a/docs/advanced-usage.md b/docs/advanced-usage.md
index 28295f9953..d0832c3f94 100644
--- a/docs/advanced-usage.md
+++ b/docs/advanced-usage.md
@@ -2399,7 +2399,7 @@ configuration is required for netty and the JDK in
We don’t have found a way yet to invoke default interface methods on
proxies without `MethodHandle`. Hence the `NodeSelection` API
-(`masters()`, `all()` and others on `RedisAdvancedClusterCommands` and
+(`primaries()`, `all()` and others on `RedisAdvancedClusterCommands` and
`RedisAdvancedClusterAsyncCommands`) do not work.
## Command execution reliability
@@ -2596,7 +2596,7 @@ means, if you execute a command twice, each resulting state is different
in comparison to the previous. Examples for non-idempotent Redis
commands are such as `LPUSH`, `PUBLISH` or `INCR`.
-Note: When using master-replica replication, different rules apply to
+Note: When using primary-replica replication, different rules apply to
*at-least-once* consistency. Replication between Redis nodes works
asynchronously. A command can be processed successfully from Lettuce’s
client perspective, but the result is not necessarily replicated to the
@@ -2659,14 +2659,14 @@ auto-replay of commands.
Lettuce sticks in clustered operations to the same rules as for
standalone operations but with one exception:
-Command execution on master nodes, which is rejected by a `MOVED`
+Command execution on primary nodes, which is rejected by a `MOVED`
response are tried to re-execute with the appropriate connection.
-`MOVED` errors occur on master nodes when a slot’s responsibility is
+`MOVED` errors occur on primary nodes when a slot’s responsibility is
moved from one cluster node to another node. Afterwards *at-least-once*
and *at-most-once* rules apply.
When the cluster topology changes, generally spoken, the cluster slots
-or master/replica state is reconfigured, following rules apply:
+or primary/replica state is reconfigured, following rules apply:
- **at-most-once** If the connection is disconnected, queued commands
are canceled and buffered commands, which were not sent, are executed
@@ -2679,4 +2679,3 @@ or master/replica state is reconfigured, following rules apply:
- If the connection is not disconnected, queued commands are finished
and buffered commands, which were not sent, are executed by using the
new cluster view
-
diff --git a/docs/ha-sharding.md b/docs/ha-sharding.md
index 67c547b65d..36ff63c952 100644
--- a/docs/ha-sharding.md
+++ b/docs/ha-sharding.md
@@ -1,75 +1,75 @@
# High-Availability and Sharding
-## Master/Replica
+## Primary/Replica
Redis can increase availability and read throughput by using
-replication. Lettuce provides dedicated Master/Replica support since 4.2
+replication. Lettuce provides dedicated Primary/Replica support since 4.2
for topologies and ReadFrom-Settings.
-Redis Master/Replica can be run standalone or together with Redis
-Sentinel, which provides automated failover and master promotion.
-Failover and master promotion is supported in Lettuce already since
-version 3.1 for master connections.
+Redis Primary/Replica can be run standalone or together with Redis
+Sentinel, which provides automated failover and primary promotion.
+Failover and primary promotion is supported in Lettuce already since
+version 3.1 for primary connections.
-Connections can be obtained from the `MasterReplica` connection provider
+Connections can be obtained from the `PrimaryReplica` connection provider
by supplying the client, Codec, and one or multiple RedisURIs.
### Redis Sentinel
-Master/Replica using Redis Sentinel uses Redis
+Primary/Replica using Redis Sentinel uses Redis
Sentinel as registry and notification source for topology events.
-Details about the master and its replicas are obtained from Redis
+Details about the primary and its replicas are obtained from Redis
Sentinel. Lettuce subscribes to Redis Sentinel events for notifications to all supplied
Sentinels.
-### Standalone Master/Replica
+### Standalone Primary/Replica
-Running a Standalone Master/Replica setup requires one seed address to
+Running a Standalone Primary/Replica setup requires one seed address to
establish a Redis connection. Providing one `RedisURI` will discover
-other nodes which belong to the Master/Replica setup and use the
+other nodes which belong to the Primary/Replica setup and use the
discovered addresses for connections. The initial URI can point either
-to a master or a replica node.
+to a primary or a replica node.
-### Static Master/Replica with predefined node addresses
+### Static Primary/Replica with predefined node addresses
In some cases, topology discovery shouldn’t be enabled, or the
discovered Redis addresses are not suited for connections. AWS
ElastiCache falls into this category. Lettuce allows to specify one or
more Redis addresses as `List` and predefine the node topology.
-Master/Replica URIs will be treated in this case as static topology, and
+Primary/Replica URIs will be treated in this case as static topology, and
no additional hosts are discovered in such case. Redis Standalone
-Master/Replica will discover the roles of the supplied `RedisURI`s and
+Primary/Replica will discover the roles of the supplied `RedisURI`s and
issue commands to the appropriate node.
### Topology discovery
-Master-Replica topologies are either static or semi-static. Redis
+Primary-Replica topologies are either static or semi-static. Redis
Standalone instances with attached replicas provide no failover/HA
mechanism. Redis Sentinel managed instances are controlled by Redis
-Sentinel and allow failover (which include master promotion). The
-`MasterReplica` API supports both mechanisms. The topology is provided
+Sentinel and allow failover (which include primary promotion). The
+`PrimaryReplica` API supports both mechanisms. The topology is provided
by a `TopologyProvider`:
-- `MasterReplicaTopologyProvider`: Dynamic topology lookup using the
+- `ReplicaTopologyProvider`: Dynamic topology lookup using the
`INFO REPLICATION` output. Replicas are listed as replicaN=… entries.
- The initial connection can either point to a master or a replica, and
+ The initial connection can either point to a primary or a replica, and
the topology provider will discover nodes. The connection needs to be
- re-established outside of Lettuce in a case of a Master/Replica
+ re-established outside of Lettuce in a case of a Primary/Replica
failover or topology changes.
- `StaticMasterReplicaTopologyProvider`: Topology is defined by the list
- of URIs and the ROLE output. MasterReplica uses only the supplied
+ of URIs and the ROLE output. PrimaryReplica uses only the supplied
nodes and won’t discover additional nodes in the setup. The connection
needs to be re-established outside of Lettuce in case of a
- Master/Replica failover or topology changes.
+ Primary/Replica failover or topology changes.
- `SentinelTopologyProvider`: Dynamic topology lookup using the Redis
Sentinel API. In particular, `SENTINEL MASTER` and `SENTINEL REPLICAS`
- output. Master/Replica failover is handled by Lettuce.
+ output. Primary/Replica failover is handled by Lettuce.
### Topology Updates
-- Standalone Master/Replica: Performs a one-time topology lookup which
+- Standalone Primary/Replica: Performs a one-time topology lookup which
remains static afterward
- Redis Sentinel: Subscribes to all Sentinels and listens for Pub/Sub
@@ -78,7 +78,7 @@ by a `TopologyProvider`:
#### Transactions
Since version 5.1, transactions and commands during a transaction are
-routed to the master node to ensure atomic transaction execution on a
+routed to the primary node to ensure atomic transaction execution on a
single node. Transactions can contain read- and write-operations so the
driver cannot decide upfront which node can be used to run the actual
transaction.
@@ -88,9 +88,9 @@ transaction.
``` java
RedisClient redisClient = RedisClient.create();
-StatefulRedisMasterReplicaConnection connection = MasterReplica.connect(redisClient, StringCodec.UTF8,
+StatefulRedisPrimaryReplicaConnection connection = PrimaryReplica.connect(redisClient, StringCodec.UTF8,
RedisURI.create("redis://localhost"));
-connection.setReadFrom(ReadFrom.MASTER_PREFERRED);
+connection.setReadFrom(ReadFrom.PRIMARY_PREFERRED);
System.out.println("Connected to Redis");
@@ -101,9 +101,9 @@ redisClient.shutdown();
``` java
RedisClient redisClient = RedisClient.create();
-StatefulRedisMasterReplicaConnection connection = MasterReplica.connect(redisClient, StringCodec.UTF8,
- RedisURI.create("redis-sentinel://localhost:26379,localhost:26380/0#mymaster"));
-connection.setReadFrom(ReadFrom.MASTER_PREFERRED);
+StatefulRedisPrimaryReplicaConnection connection = PrimaryReplica.connect(redisClient, StringCodec.UTF8,
+ RedisURI.create("redis-sentinel://localhost:26379,localhost:26380/0#myprimary"));
+connection.setReadFrom(ReadFrom.PRIMARY_PREFERRED);
System.out.println("Connected to Redis");
@@ -118,9 +118,9 @@ List nodes = Arrays.asList(RedisURI.create("redis://host1"),
RedisURI.create("redis://host2"),
RedisURI.create("redis://host3"));
-StatefulRedisMasterReplicaConnection connection = MasterReplica
+StatefulRedisPrimaryReplicaConnection connection = PrimaryReplica
.connect(redisClient, StringCodec.UTF8, nodes);
-connection.setReadFrom(ReadFrom.MASTER_PREFERRED);
+connection.setReadFrom(ReadFrom.PRIMARY_PREFERRED);
System.out.println("Connected to Redis");
@@ -138,10 +138,10 @@ Sentinel-managed nodes in multiple ways:
Redis Sentinel commands
2. Using Redis Sentinel to [connect to a
- master](#redis-discovery-using-redis-sentinel)
+ primary](#redis-discovery-using-redis-sentinel)
-3. Using Redis Sentinel to connect to master nodes and replicas through
- the {master-replica-api-link}.
+3. Using Redis Sentinel to connect to primary nodes and replicas through
+ the `PrimaryReplica` API.
In both cases, you need to supply a `RedisURI` since the Redis Sentinel
integration supports multiple Sentinel hosts to provide high
@@ -154,7 +154,7 @@ asynchronous connections and no connection pooling.
Lettuce exposes an API to interact with Redis Sentinel nodes directly.
This is useful for performing administrative tasks using Lettuce. You
-can monitor new master nodes, query master addresses, replicas and much
+can monitor new primary nodes, query primary addresses, replicas and much
more. A connection to a Redis Sentinel node is established by
`RedisClient.connectSentinel()`. Use a [Publish/Subscribe
connection](user-guide/pubsub.md) to subscribe to Sentinel events.
@@ -163,17 +163,17 @@ connection](user-guide/pubsub.md) to subscribe to Sentinel events.
One or more Redis Sentinels can monitor Redis instances . These Redis
instances are usually operated together with a replica of the Redis
-instance. Once the master goes down, the replica is promoted to a
-master. Once a master instance is not reachable anymore, the failover
+instance. Once the primary goes down, the replica is promoted to a
+primary. Once a primary instance is not reachable anymore, the failover
process is started by the Redis Sentinels. Usually, the client
connection is terminated. The disconnect can result in any of the
following options:
-1. The master comes back: The connection is restored to the Redis
+1. The primary comes back: The connection is restored to the Redis
instance
-2. A replica is promoted to a master: Lettuce performs an address
- lookup using the `masterId`. As soon as the Redis Sentinel provides
+2. A replica is promoted to a primary: Lettuce performs an address
+ lookup using the `primaryId`. As soon as the Redis Sentinel provides
an address the connection is restored to the new Redis instance
Read more at
@@ -186,11 +186,11 @@ RedisClient client = new RedisClient(redisUri);
RedisSentinelAsyncConnection connection = client.connectSentinelAsync();
-Map map = connection.master("mymaster").get();
+Map map = connection.primary("myprimary").get();
```
``` java
-RedisURI redisUri = RedisURI.Builder.sentinel("sentinelhost1", "mymaster").withSentinel("sentinelhost2").build();
+RedisURI redisUri = RedisURI.Builder.sentinelPrimary("sentinelhost1", "myprimary").withSentinel("sentinelhost2").build();
RedisClient client = RedisClient.create(redisUri);
RedisConnection connection = client.connect();
@@ -198,7 +198,7 @@ RedisConnection connection = client.connect();
!!! NOTE
Every time you connect to a Redis instance using Redis Sentinel, the
- Redis master is looked up using a new connection to a Redis Sentinel.
+ Redis primary is looked up using a new connection to a Redis Sentinel.
This can be time-consuming, especially when multiple Redis Sentinels
are used and one or more of them are not reachable.
@@ -245,7 +245,7 @@ users of the cluster connection might be affected.
### Command routing
The [concept of Redis Cluster](https://redis.io/docs/latest/operate/oss_and_stack/management/scaling/)
-bases on sharding. Every master node within the cluster handles one or
+bases on sharding. Every primary node within the cluster handles one or
more slots. Slots are the [unit of
sharding](https://redis.io/docs/latest/operate/oss_and_stack/management/scaling/#redis-cluster-data-sharding)
and calculated from the commands' key using `CRC16 MOD 16384`. Hash
@@ -277,7 +277,7 @@ Following commands are supported for cross-slot command execution:
- `DEL`: Delete the `KEY`s. Returns the number of keys that were
removed.
-- `EXISTS`: Count the number of `KEY`s that exist across the master
+- `EXISTS`: Count the number of `KEY`s that exist across the primary
nodes being responsible for the particular key.
- `MGET`: Get the values of all given `KEY`s. Returns the values in the
@@ -297,16 +297,16 @@ Following commands are executed on multiple cluster nodes operations:
- `CLIENT SETNAME`: Set the client name on all known cluster node
connections. Returns always `OK`.
-- `KEYS`: Return/Stream all keys that are stored on all masters.
+- `KEYS`: Return/Stream all keys that are stored on all primaries.
-- `DBSIZE`: Return the number of keys that are stored on all masters.
+- `DBSIZE`: Return the number of keys that are stored on all primaries.
-- `FLUSHALL`: Flush all data on the cluster masters. Returns always
+- `FLUSHALL`: Flush all data on the cluster primaries. Returns always
`OK`.
-- `FLUSHDB`: Flush all data on the cluster masters. Returns always `OK`.
+- `FLUSHDB`: Flush all data on the cluster primaries. Returns always `OK`.
-- `RANDOMKEY`: Return a random key from a random master.
+- `RANDOMKEY`: Return a random key from a random primary.
- `SCAN`: Scan the keyspace across the whole cluster according to
`ReadFrom` settings.
@@ -333,12 +333,12 @@ Cross-slot command execution is available on the following APIs:
### Execution of commands on one or multiple cluster nodes
Sometimes commands have to be executed on multiple cluster nodes. The
-advanced cluster API allows to select a set of nodes (e.g. all masters,
+advanced cluster API allows to select a set of nodes (e.g. all primaries,
all replicas) and trigger a command on this set.
``` java
RedisAdvancedClusterAsyncCommands async = clusterClient.connect().async();
-AsyncNodeSelection replicas = connection.slaves();
+AsyncNodeSelection replicas = connection.replicas();
AsyncExecutions> executions = replicas.commands().keys("*");
executions.forEach(result -> result.thenAccept(keys -> System.out.println(keys)));
@@ -354,7 +354,7 @@ selection updates its node set upon a [cluster topology view
refresh](#refreshing-the-cluster-topology-view). Node
selections can be constructed by the following presets:
-- masters
+- primaries
- replicas (operate on connections with activated `READONLY` mode)
@@ -376,7 +376,7 @@ feedback from the users. So feel free to contribute.
### Refreshing the cluster topology view
The Redis Cluster configuration may change at runtime. New nodes can be
-added, the master for a specific slot can change. Lettuce handles
+added, the primary for a specific slot can change. Lettuce handles
`MOVED` and `ASK` redirects transparently but in case too many commands
run into redirects, you should refresh the cluster topology view. The
topology is bound to a `RedisClusterClient` instance. All cluster
@@ -516,22 +516,22 @@ The ReadFrom setting describes how Lettuce routes read operations to
replica nodes.
By default, Lettuce routes its read operations in multi-node connections
-to the master node. Reading from the master returns the most recent
+to the primary node. Reading from the primary returns the most recent
version of the data because write operations are issued to the single
-master node. Reading from masters guarantees strong consistency.
+primary node. Reading from primaries guarantees strong consistency.
You can reduce latency or improve read throughput by distributing reads
to replica members for applications that do not require fully up-to-date
data.
-Be careful if using other ReadFrom settings than `MASTER`. Settings
-other than `MASTER` may return stale data because the replication is
+Be careful if using other ReadFrom settings than `PRIMARY`. Settings
+other than `PRIMARY` may return stale data because the replication is
asynchronous. Data in the replicas may not hold the most recent data.
### Redis Cluster
Redis Cluster is a multi-node operated Redis setup that uses one or more
-master nodes and allows to setup replica nodes. Redis Cluster
+primary nodes and allows to setup replica nodes. Redis Cluster
connections allow to set a `ReadFrom` setting on connection level. This
setting applies for all read operations on this connection.
@@ -549,37 +549,37 @@ connection.close();
client.shutdown();
```
-### Master/Replica connections ("Master/Slave")
+### Primary/Replica connections (legacy master/slave)
-Redis nodes can be operated in a Master/Replica setup to achieve
-availability and performance. Master/Replica setups can be run either
+Redis nodes can be operated in a Primary/Replica setup to achieve
+availability and performance. Primary/Replica setups can be run either
Standalone or managed using Redis Sentinel. Lettuce allows to use
-replica nodes for read operations by using the `MasterReplica` API that
-supports both Master/Replica setups:
+replica nodes for read operations by using the `PrimaryReplica` API that
+supports both Primary/Replica setups:
-1. Redis Standalone Master/Replica (no failover)
+1. Redis Standalone Primary/Replica (no failover)
-2. Redis Sentinel Master/Replica (Sentinel-managed failover)
+2. Redis Sentinel Primary/Replica (Sentinel-managed failover)
The resulting connection uses in any case the primary connection-point
to dispatch non-read operations.
#### Redis Sentinel
-Master/Replica with Redis Sentinel is very similar to regular Redis
-Sentinel operations. When the master fails over, a replica is promoted
-by Redis Sentinel to the new master and the client obtains the new
+Primary/Replica with Redis Sentinel is very similar to regular Redis
+Sentinel operations. When the primary fails over, a replica is promoted
+by Redis Sentinel to the new primary and the client obtains the new
topology from Redis Sentinel.
-Connections to Master/Replica require one or more Redis Sentinel
-connection points and a master name. The primary connection point is the
-Sentinel monitored master node.
+Connections to Primary/Replica require one or more Redis Sentinel
+connection points and a primary name. The primary connection point is the
+Sentinel monitored primary node.
``` java
-RedisURI sentinelUri = RedisURI.Builder.sentinel("sentinel-host", 26379, "master-name").build();
+RedisURI sentinelUri = RedisURI.Builder.sentinelPrimary("sentinel-host", 26379, "primary-name").build();
RedisClient client = RedisClient.create();
-StatefulRedisMasterReplicaConnection connection = MasterReplica.connect(
+StatefulRedisPrimaryReplicaConnection connection = PrimaryReplica.connect(
client,
StringCodec.UTF8
sentinelUri);
@@ -594,23 +594,23 @@ client.shutdown();
#### Redis Standalone
-Master/Replica with Redis Standalone is very similar to regular Redis
-Standalone operations. A Redis Standalone Master/Replica setup is static
+Primary/Replica with Redis Standalone is very similar to regular Redis
+Standalone operations. A Redis Standalone Primary/Replica setup is static
and provides no built-in failover. Replicas are read from the Redis
-master node’s `INFO` command.
+primary node’s `INFO` command.
-Connecting to Redis Standalone Master/Replica nodes requires connections
-to use the Redis master for the `RedisURI`. The node used within the
+Connecting to Redis Standalone Primary/Replica nodes requires connections
+to use the Redis primary for the `RedisURI`. The node used within the
`RedisURI` is the primary connection point.
``` java
-RedisURI masterUri = RedisURI.Builder.redis("master-host", 6379).build();
+RedisURI primaryUri = RedisURI.Builder.redis("primary-host", 6379).build();
RedisClient client = RedisClient.create();
-StatefulRedisMasterReplicaConnection connection = MasterReplica.connect(
+StatefulRedisPrimaryReplicaConnection connection = PrimaryReplica.connect(
client,
StringCodec.UTF8,
- masterUri);
+ primaryUri);
connection.setReadFrom(ReadFrom.REPLICA);
@@ -620,42 +620,42 @@ connection.close();
client.shutdown();
```
-### Use Cases for non-master reads
+### Use Cases for non-primary reads
-The following use cases are common for using non-master read settings
+The following use cases are common for using non-primary read settings
and encourage eventual consistency:
- Providing local reads for geographically distributed applications. If
you have Redis and application servers in multiple data centers, you
may consider having a geographically distributed cluster. Using the
`LOWEST_LATENCY` setting allows the client to read from the
- lowest-latency members, rather than always reading from the master
+ lowest-latency members, rather than always reading from the primary
node.
-- Maintaining availability during a failover. Use `MASTER_PREFERRED` if
- you want an application to read from the master by default, but to
- allow stale reads from replicas when the master node is unavailable.
- `MASTER_PREFERRED` allows a "read-only mode" for your application
+- Maintaining availability during a failover. Use `PRIMARY_PREFERRED` if
+ you want an application to read from the primary by default, but to
+ allow stale reads from replicas when the primary node is unavailable.
+ `PRIMARY_PREFERRED` allows a "read-only mode" for your application
during a failover.
- Increase read throughput by allowing stale reads If you want to
increase your read throughput by adding additional replica nodes to
your cluster Use `REPLICA` to read explicitly from replicas and reduce
- read load on the master node. Using replica reads can highly lead to
+ read load on the primary node. Using replica reads can highly lead to
stale reads.
### Read from settings
-All `ReadFrom` settings except `MASTER` may return stale data because
+All `ReadFrom` settings except `PRIMARY` may return stale data because
replicas replication is asynchronous and requires some delay. You need
to ensure that your application can tolerate stale data.
| Setting | Description |
|---------------------|--------------------------------------------------------------------------------|
-| `MASTER` | Default mode. Read from the current master node. |
-| `MASTER_PREFERRED` | Read from the master, but if it is unavailable, read from replica nodes. |
+| `PRIMARY` | Default mode. Read from the current primary node. |
+| `PRIMARY_PREFERRED` | Read from the primary, but if it is unavailable, read from replica nodes. |
| `REPLICA` | Read from replica nodes. |
-| `REPLICA_PREFERRED` | Read from the replica nodes, but if none is unavailable, read from the master. |
+| `REPLICA_PREFERRED` | Read from the replica nodes, but if none is unavailable, read from the primary. |
| `LOWEST_LATENCY` | Read from any node of the cluster with the lowest latency. |
| `ANY` | Read from any node of the cluster. |
| `ANY_REPLICA` | Read from any replica of the cluster. |
@@ -667,4 +667,3 @@ to ensure that your application can tolerate stale data.
Custom read settings can be implemented by extending the
`io.lettuce.core.ReadFrom` class.
-
diff --git a/docs/new-features.md b/docs/new-features.md
index 0eec2f8230..b2acc23b3e 100644
--- a/docs/new-features.md
+++ b/docs/new-features.md
@@ -142,7 +142,7 @@
- Add support for [Redis
Streams](https://redis.io/topics/streams-intro).
-- Asynchronous `connect()` for Master/Replica connections.
+- Asynchronous `connect()` for Primary/Replica connections.
- [Asynchronous Connection Pooling](advanced-usage.md#asynchronous-connection-pooling)
through `AsyncConnectionPoolSupport` and `AsyncPool`.
@@ -166,7 +166,7 @@
- Reactive `ScanStream` to iterate over the keyspace using `SCAN`
commands.
-- Transactions using Master/Replica connections are bound to the master
+- Transactions using Primary/Replica connections are bound to the primary
node.
## What’s new in Lettuce 5.0
@@ -196,4 +196,3 @@
- HTML and PDF reference documentation along with a new project website:
.
-
diff --git a/docs/redis-command-interfaces.md b/docs/redis-command-interfaces.md
index 6a644bdc85..3f0f48f3cc 100644
--- a/docs/redis-command-interfaces.md
+++ b/docs/redis-command-interfaces.md
@@ -155,7 +155,7 @@ public interface MixedCommands extends Commands {
to determine a command intent (whether a command is a read-only one).
Commands are resolved case-sensitive. Use lower-case command names in
`@Command` to resolve to an unknown command to e.g. enforce
- master-routing.
+ primary-routing.
### CamelCase in method names
@@ -581,4 +581,3 @@ Errors are transported through `RedisFuture`. Synchronous commands don’t
receive any result/exception signal except if the batch is flushed
through a synchronous method call. Synchronous flushing throws
`BatchException` containing the failed commands.
-
diff --git a/docs/user-guide/async-api.md b/docs/user-guide/async-api.md
index c11c350d44..aa4537a617 100644
--- a/docs/user-guide/async-api.md
+++ b/docs/user-guide/async-api.md
@@ -458,14 +458,14 @@ couple of `…Either()` methods are available on a `CompletionStage`,
see the [Java 8 API docs](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html)
for the full reference. The either-or pattern consumes the value from
the first future that is completed. A good example might be two services
-returning the same data, for instance, a Master-Replica scenario, but
+returning the same data, for instance, a Primary-Replica scenario, but
you want to return the data as fast as possible:
``` java
-RedisStringAsyncCommands master = masterClient.connect().async();
+RedisStringAsyncCommands primary = primaryClient.connect().async();
RedisStringAsyncCommands replica = replicaClient.connect().async();
-RedisFuture future = master.get("key");
+RedisFuture future = primary.get("key");
future.acceptEither(replica.get("key"), new Consumer() {
@Override
public void accept(String value) {
@@ -568,4 +568,4 @@ Runnable listener = new Runnable() {
};
set.thenRun(listener);
-```
\ No newline at end of file
+```
diff --git a/docs/user-guide/pubsub.md b/docs/user-guide/pubsub.md
index 96186f4103..f8c0e43d24 100644
--- a/docs/user-guide/pubsub.md
+++ b/docs/user-guide/pubsub.md
@@ -99,7 +99,7 @@ connection.addListener(new RedisClusterPubSubListener() { ... })
connection.setNodeMessagePropagation(true);
RedisPubSubCommands sync = connection.sync();
-sync.masters().commands().subscribe("__keyspace@0__:*");
+sync.primaries().commands().subscribe("__keyspace@0__:*");
```
There are two things to pay special attention to:
@@ -107,12 +107,12 @@ There are two things to pay special attention to:
1. Replication: Keys replicated to replica nodes, especially
considering expiry, generate keyspace events on all nodes holding
the key. If a key expires and it is replicated, it will expire on
- the master and all replicas. Each Redis server will emit keyspace
- events. Subscribing to non-master nodes, therefore, will let your
+ the primary and all replicas. Each Redis server will emit keyspace
+ events. Subscribing to non-primary nodes, therefore, will let your
application see multiple events of the same type for the same key
because of Redis distributed nature.
2. Topology Changes: Subscriptions are issued either by using the
NodeSelection API or by calling `subscribe(…)` on the individual
cluster node connections. Subscription registrations are not
- propagated to new nodes that are added on a topology change.
\ No newline at end of file
+ propagated to new nodes that are added on a topology change.
diff --git a/src/test/java/io/lettuce/core/RedisURIUnitTests.java b/src/test/java/io/lettuce/core/RedisURIUnitTests.java
index e47e38fad6..68dc0accd7 100644
--- a/src/test/java/io/lettuce/core/RedisURIUnitTests.java
+++ b/src/test/java/io/lettuce/core/RedisURIUnitTests.java
@@ -149,12 +149,13 @@ void sentinelUriTest() {
RedisURI redisURI = RedisURI.create("redis-sentinel://auth@h1:222,h2,h3:1234/5?sentinelMasterId=masterId");
assertThat(redisURI.getSentinelMasterId()).isEqualTo("masterId");
+ assertThat(redisURI.getSentinelPrimaryId()).isEqualTo("masterId");
assertThat(redisURI.getSentinels().get(0).getPort()).isEqualTo(222);
assertThat(redisURI.getSentinels().get(1).getPort()).isEqualTo(RedisURI.DEFAULT_SENTINEL_PORT);
assertThat(redisURI.getSentinels().get(2).getPort()).isEqualTo(1234);
assertThat(redisURI.getDatabase()).isEqualTo(5);
- assertThat(redisURI).hasToString("redis-sentinel://****@h1:222,h2,h3:1234/5?sentinelMasterId=masterId");
+ assertThat(redisURI).hasToString("redis-sentinel://****@h1:222,h2,h3:1234/5?sentinelPrimaryId=masterId");
}
@Test
@@ -163,7 +164,7 @@ void sentinelSecureUriTest() {
RedisURI redisURI = RedisURI.create("rediss-sentinel://auth@h1:222,h2,h3:1234/5?sentinelMasterId=masterId");
assertThat(redisURI.isSsl()).isTrue();
- assertThat(redisURI).hasToString("rediss-sentinel://****@h1:222,h2,h3:1234/5?sentinelMasterId=masterId");
+ assertThat(redisURI).hasToString("rediss-sentinel://****@h1:222,h2,h3:1234/5?sentinelPrimaryId=masterId");
}
@Test
diff --git a/src/test/java/io/lettuce/examples/ConnectToMasterSlaveUsingElastiCacheCluster.java b/src/test/java/io/lettuce/examples/ConnectToMasterSlaveUsingElastiCacheCluster.java
index 32303bdfaa..be05ab1700 100644
--- a/src/test/java/io/lettuce/examples/ConnectToMasterSlaveUsingElastiCacheCluster.java
+++ b/src/test/java/io/lettuce/examples/ConnectToMasterSlaveUsingElastiCacheCluster.java
@@ -3,34 +3,15 @@
import java.util.Arrays;
import java.util.List;
-import io.lettuce.core.ReadFrom;
-import io.lettuce.core.RedisClient;
-import io.lettuce.core.RedisURI;
-import io.lettuce.core.codec.StringCodec;
-import io.lettuce.core.masterreplica.MasterReplica;
-import io.lettuce.core.masterreplica.StatefulRedisMasterReplicaConnection;
-
/**
* @author Mark Paluch
+ * @deprecated since 7.3, use {@link ConnectToPrimaryReplicaUsingElastiCacheCluster}.
*/
+@Deprecated
public class ConnectToMasterSlaveUsingElastiCacheCluster {
public static void main(String[] args) {
-
- // Syntax: redis://[password@]host[:port][/databaseNumber]
- RedisClient redisClient = RedisClient.create();
-
- List nodes = Arrays.asList(RedisURI.create("redis://host1"), RedisURI.create("redis://host2"),
- RedisURI.create("redis://host3"));
-
- StatefulRedisMasterReplicaConnection connection = MasterReplica.connect(redisClient, StringCodec.UTF8,
- nodes);
- connection.setReadFrom(ReadFrom.UPSTREAM_PREFERRED);
-
- System.out.println("Connected to Redis");
-
- connection.close();
- redisClient.shutdown();
+ ConnectToPrimaryReplicaUsingElastiCacheCluster.main(args);
}
}
diff --git a/src/test/java/io/lettuce/examples/ConnectToMasterSlaveUsingRedisSentinel.java b/src/test/java/io/lettuce/examples/ConnectToMasterSlaveUsingRedisSentinel.java
index d08200e224..cf75e84236 100644
--- a/src/test/java/io/lettuce/examples/ConnectToMasterSlaveUsingRedisSentinel.java
+++ b/src/test/java/io/lettuce/examples/ConnectToMasterSlaveUsingRedisSentinel.java
@@ -1,29 +1,14 @@
package io.lettuce.examples;
-import io.lettuce.core.ReadFrom;
-import io.lettuce.core.RedisClient;
-import io.lettuce.core.RedisURI;
-import io.lettuce.core.codec.StringCodec;
-import io.lettuce.core.masterreplica.MasterReplica;
-import io.lettuce.core.masterreplica.StatefulRedisMasterReplicaConnection;
-
/**
* @author Mark Paluch
+ * @deprecated since 7.3, use {@link ConnectToPrimaryReplicaUsingRedisSentinel}.
*/
+@Deprecated
public class ConnectToMasterSlaveUsingRedisSentinel {
public static void main(String[] args) {
- // Syntax: redis-sentinel://[password@]host[:port][,host2[:port2]][/databaseNumber]#sentinelMasterId
- RedisClient redisClient = RedisClient.create();
-
- StatefulRedisMasterReplicaConnection connection = MasterReplica.connect(redisClient, StringCodec.UTF8,
- RedisURI.create("redis-sentinel://localhost:26379,localhost:26380/0#mymaster"));
- connection.setReadFrom(ReadFrom.UPSTREAM_PREFERRED);
-
- System.out.println("Connected to Redis");
-
- connection.close();
- redisClient.shutdown();
+ ConnectToPrimaryReplicaUsingRedisSentinel.main(args);
}
}
diff --git a/src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingElastiCacheCluster.java b/src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingElastiCacheCluster.java
new file mode 100644
index 0000000000..4da86246a9
--- /dev/null
+++ b/src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingElastiCacheCluster.java
@@ -0,0 +1,37 @@
+package io.lettuce.examples;
+
+import java.util.Arrays;
+import java.util.List;
+
+import io.lettuce.core.ReadFrom;
+import io.lettuce.core.RedisClient;
+import io.lettuce.core.RedisURI;
+import io.lettuce.core.codec.StringCodec;
+import io.lettuce.core.primaryreplica.PrimaryReplica;
+import io.lettuce.core.primaryreplica.StatefulRedisPrimaryReplicaConnection;
+
+/**
+ * @author
+ * @since 7.3
+ */
+public class ConnectToPrimaryReplicaUsingElastiCacheCluster {
+
+ public static void main(String[] args) {
+
+ // Syntax: redis://[password@]host[:port][/databaseNumber]
+ RedisClient redisClient = RedisClient.create();
+
+ List nodes = Arrays.asList(RedisURI.create("redis://host1"), RedisURI.create("redis://host2"),
+ RedisURI.create("redis://host3"));
+
+ StatefulRedisPrimaryReplicaConnection connection = PrimaryReplica.connect(redisClient, StringCodec.UTF8,
+ nodes);
+ connection.setReadFrom(ReadFrom.PRIMARY_PREFERRED);
+
+ System.out.println("Connected to Redis");
+
+ connection.close();
+ redisClient.shutdown();
+ }
+
+}
diff --git a/src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingRedisSentinel.java b/src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingRedisSentinel.java
new file mode 100644
index 0000000000..5c0761778c
--- /dev/null
+++ b/src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingRedisSentinel.java
@@ -0,0 +1,30 @@
+package io.lettuce.examples;
+
+import io.lettuce.core.ReadFrom;
+import io.lettuce.core.RedisClient;
+import io.lettuce.core.RedisURI;
+import io.lettuce.core.codec.StringCodec;
+import io.lettuce.core.primaryreplica.PrimaryReplica;
+import io.lettuce.core.primaryreplica.StatefulRedisPrimaryReplicaConnection;
+
+/**
+ * @author
+ * @since 7.3
+ */
+public class ConnectToPrimaryReplicaUsingRedisSentinel {
+
+ public static void main(String[] args) {
+ // Syntax: redis-sentinel://[password@]host[:port][,host2[:port2]][/databaseNumber]#sentinelPrimaryId
+ RedisClient redisClient = RedisClient.create();
+
+ StatefulRedisPrimaryReplicaConnection connection = PrimaryReplica.connect(redisClient, StringCodec.UTF8,
+ RedisURI.create("redis-sentinel://localhost:26379,localhost:26380/0#myprimary"));
+ connection.setReadFrom(ReadFrom.PRIMARY_PREFERRED);
+
+ System.out.println("Connected to Redis");
+
+ connection.close();
+ redisClient.shutdown();
+ }
+
+}
diff --git a/src/test/java/io/lettuce/examples/ConnectToRedisUsingRedisSentinel.java b/src/test/java/io/lettuce/examples/ConnectToRedisUsingRedisSentinel.java
index 24a032e925..5a93295f39 100644
--- a/src/test/java/io/lettuce/examples/ConnectToRedisUsingRedisSentinel.java
+++ b/src/test/java/io/lettuce/examples/ConnectToRedisUsingRedisSentinel.java
@@ -10,8 +10,8 @@ public class ConnectToRedisUsingRedisSentinel {
public static void main(String[] args) {
- // Syntax: redis-sentinel://[password@]host[:port][,host2[:port2]][/databaseNumber]#sentinelMasterId
- RedisClient redisClient = RedisClient.create("redis-sentinel://localhost:26379,localhost:26380/0#mymaster");
+ // Syntax: redis-sentinel://[password@]host[:port][,host2[:port2]][/databaseNumber]#sentinelPrimaryId
+ RedisClient redisClient = RedisClient.create("redis-sentinel://localhost:26379,localhost:26380/0#myprimary");
StatefulRedisConnection connection = redisClient.connect();
diff --git a/src/test/resources/spring-test.xml b/src/test/resources/spring-test.xml
index 9e2f82bf67..ba33c821ed 100644
--- a/src/test/resources/spring-test.xml
+++ b/src/test/resources/spring-test.xml
@@ -8,8 +8,8 @@
-
-
-
+
+
+
From eae4f4ef52300e2c7cc975dc63fa4e50d3d68343 Mon Sep 17 00:00:00 2001
From: Yeongjae Kim
Date: Sun, 11 Jan 2026 21:42:24 +0900
Subject: [PATCH 5/5] Add author annotation to new primary/replica classes
#3463
---
.../java/io/lettuce/core/models/role/RedisPrimaryInstance.java | 2 +-
.../java/io/lettuce/core/primaryreplica/PrimaryReplica.java | 2 +-
.../primaryreplica/StatefulRedisPrimaryReplicaConnection.java | 2 +-
.../ConnectToPrimaryReplicaUsingElastiCacheCluster.java | 2 +-
.../examples/ConnectToPrimaryReplicaUsingRedisSentinel.java | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/main/java/io/lettuce/core/models/role/RedisPrimaryInstance.java b/src/main/java/io/lettuce/core/models/role/RedisPrimaryInstance.java
index 04236fb315..9ed8b65dd5 100644
--- a/src/main/java/io/lettuce/core/models/role/RedisPrimaryInstance.java
+++ b/src/main/java/io/lettuce/core/models/role/RedisPrimaryInstance.java
@@ -5,7 +5,7 @@
/**
* Represents an upstream (primary) instance.
*
- * @author
+ * @author yeong0jae
* @since 7.3
*/
@SuppressWarnings("serial")
diff --git a/src/main/java/io/lettuce/core/primaryreplica/PrimaryReplica.java b/src/main/java/io/lettuce/core/primaryreplica/PrimaryReplica.java
index f20e6fdad7..091cee5633 100644
--- a/src/main/java/io/lettuce/core/primaryreplica/PrimaryReplica.java
+++ b/src/main/java/io/lettuce/core/primaryreplica/PrimaryReplica.java
@@ -15,7 +15,7 @@
* {@link io.lettuce.core.ReadFrom}.
*
*
- * @author Mark Paluch
+ * @author yeong0jae
* @since 7.3
*/
@SuppressWarnings("deprecation")
diff --git a/src/main/java/io/lettuce/core/primaryreplica/StatefulRedisPrimaryReplicaConnection.java b/src/main/java/io/lettuce/core/primaryreplica/StatefulRedisPrimaryReplicaConnection.java
index 9fcd27c839..ecae832610 100644
--- a/src/main/java/io/lettuce/core/primaryreplica/StatefulRedisPrimaryReplicaConnection.java
+++ b/src/main/java/io/lettuce/core/primaryreplica/StatefulRedisPrimaryReplicaConnection.java
@@ -8,7 +8,7 @@
*
* @param Key type.
* @param Value type.
- * @author
+ * @author yeong0jae
* @since 7.3
*/
public interface StatefulRedisPrimaryReplicaConnection extends StatefulRedisConnection {
diff --git a/src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingElastiCacheCluster.java b/src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingElastiCacheCluster.java
index 4da86246a9..a9ae59807c 100644
--- a/src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingElastiCacheCluster.java
+++ b/src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingElastiCacheCluster.java
@@ -11,7 +11,7 @@
import io.lettuce.core.primaryreplica.StatefulRedisPrimaryReplicaConnection;
/**
- * @author
+ * @author yeong0jae
* @since 7.3
*/
public class ConnectToPrimaryReplicaUsingElastiCacheCluster {
diff --git a/src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingRedisSentinel.java b/src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingRedisSentinel.java
index 5c0761778c..d833bb969d 100644
--- a/src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingRedisSentinel.java
+++ b/src/test/java/io/lettuce/examples/ConnectToPrimaryReplicaUsingRedisSentinel.java
@@ -8,7 +8,7 @@
import io.lettuce.core.primaryreplica.StatefulRedisPrimaryReplicaConnection;
/**
- * @author
+ * @author yeong0jae
* @since 7.3
*/
public class ConnectToPrimaryReplicaUsingRedisSentinel {