DATAREDIS-580 - Support Master/Slave connections with ReadFrom settings using Lettuce.
We now allow configuration of ReadFrom settings using the Lettuce driver to enable slave reads. If ReadFrom is configured, we opt-in to Master/Slave connections instead of plain connections. Master/Slave connections route commands to the configured type of node depending on whether the command is a read or write command. LettuceClientConfiguration configuration = LettuceClientConfiguration.builder().readFrom(ReadFrom.SLAVE).build(); ReadFrom is available for: * Static Master/Slave Redis without Redis Sentinel * Sentinel-Managed Master/Slave Redis * Redis Cluster ReadFrom is not configured for Pub/Sub connections or connections to the actual Sentinel servers. Original Pull Request: #287
This commit is contained in:
committed by
Christoph Strobl
parent
9775734f6f
commit
b414fdf6f1
@@ -23,6 +23,7 @@ import static org.junit.Assume.*;
|
||||
|
||||
import io.lettuce.core.EpollProvider;
|
||||
import io.lettuce.core.KqueueProvider;
|
||||
import io.lettuce.core.ReadFrom;
|
||||
import io.lettuce.core.RedisException;
|
||||
import io.lettuce.core.api.async.RedisAsyncCommands;
|
||||
import io.lettuce.core.api.reactive.BaseRedisReactiveCommands;
|
||||
@@ -385,6 +386,28 @@ public class LettuceConnectionFactoryTests {
|
||||
factory.destroy();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-580
|
||||
public void factoryUsesMasterSlaveConnections() {
|
||||
|
||||
LettuceClientConfiguration configuration = LettuceTestClientConfiguration.builder().readFrom(ReadFrom.SLAVE)
|
||||
.build();
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(SettingsUtils.standaloneConfiguration(),
|
||||
configuration);
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
RedisConnection connection = factory.getConnection();
|
||||
|
||||
try {
|
||||
assertThat(connection.ping(), is(equalTo("PONG")));
|
||||
assertThat(connection.info().getProperty("role"), is(equalTo("slave")));
|
||||
} finally {
|
||||
this.connection.close();
|
||||
}
|
||||
|
||||
factory.destroy();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-576
|
||||
public void connectionAppliesClientName() {
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ import io.lettuce.core.api.sync.RedisCommands;
|
||||
import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands;
|
||||
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
@@ -43,7 +45,8 @@ public abstract class LettuceReactiveClusterCommandsTestsBase {
|
||||
assumeThat(clientProvider.test(), is(true));
|
||||
nativeCommands = clientProvider.getClient().connect().sync();
|
||||
connection = new LettuceReactiveRedisClusterConnection(
|
||||
new ClusterConnectionProvider(clientProvider.getClient(), LettuceReactiveRedisConnection.CODEC),
|
||||
new ClusterConnectionProvider(clientProvider.getClient(), LettuceReactiveRedisConnection.CODEC,
|
||||
Optional.empty()),
|
||||
clientProvider.getClient());
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -89,9 +90,9 @@ public abstract class LettuceReactiveCommandsTestsBase {
|
||||
List<Object[]> parameters = new ArrayList<>();
|
||||
|
||||
StandaloneConnectionProvider standaloneProvider = new StandaloneConnectionProvider(standalone.getClient(),
|
||||
LettuceReactiveRedisConnection.CODEC);
|
||||
LettuceReactiveRedisConnection.CODEC, Optional.empty());
|
||||
StandaloneConnectionProvider nativeConnectionProvider = new StandaloneConnectionProvider(standalone.getClient(),
|
||||
StringCodec.UTF8);
|
||||
StringCodec.UTF8, Optional.empty());
|
||||
|
||||
parameters.add(new Object[] { standaloneProvider, nativeConnectionProvider, "Standalone" });
|
||||
parameters.add(new Object[] {
|
||||
@@ -101,9 +102,9 @@ public abstract class LettuceReactiveCommandsTestsBase {
|
||||
if (cluster.test()) {
|
||||
|
||||
ClusterConnectionProvider clusterProvider = new ClusterConnectionProvider(cluster.getClient(),
|
||||
LettuceReactiveRedisConnection.CODEC);
|
||||
LettuceReactiveRedisConnection.CODEC, Optional.empty());
|
||||
ClusterConnectionProvider nativeClusterConnectionProvider = new ClusterConnectionProvider(cluster.getClient(),
|
||||
StringCodec.UTF8);
|
||||
StringCodec.UTF8, Optional.empty());
|
||||
|
||||
parameters.add(new Object[] { clusterProvider, nativeClusterConnectionProvider, "Cluster" });
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import static org.hamcrest.core.Is.is;
|
||||
import static org.hamcrest.core.IsEqual.equalTo;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import io.lettuce.core.ReadFrom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -33,8 +35,10 @@ import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.springframework.data.redis.ConnectionFactoryTracker;
|
||||
import org.springframework.data.redis.SettingsUtils;
|
||||
import org.springframework.data.redis.connection.AbstractConnectionIntegrationTests;
|
||||
import org.springframework.data.redis.connection.DefaultStringRedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisSentinelConnection;
|
||||
import org.springframework.data.redis.connection.RedisServer;
|
||||
@@ -170,4 +174,64 @@ public class LettuceSentinelIntegrationTests extends AbstractConnectionIntegrati
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-580
|
||||
public void factoryWithReadFromMasterSettings() {
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(SENTINEL_CONFIG,
|
||||
LettuceTestClientConfiguration.builder().readFrom(ReadFrom.MASTER).build());
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
ConnectionFactoryTracker.add(factory);
|
||||
|
||||
StringRedisConnection connection = new DefaultStringRedisConnection(factory.getConnection());
|
||||
|
||||
try {
|
||||
assertThat(connection.ping(), is(equalTo("PONG")));
|
||||
assertThat(connection.info().getProperty("role"), is(equalTo("master")));
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-580
|
||||
public void factoryWithReadFromSlaveSettings() {
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(SENTINEL_CONFIG,
|
||||
LettuceTestClientConfiguration.builder().readFrom(ReadFrom.SLAVE).build());
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
ConnectionFactoryTracker.add(factory);
|
||||
|
||||
StringRedisConnection connection = new DefaultStringRedisConnection(factory.getConnection());
|
||||
|
||||
try {
|
||||
assertThat(connection.ping(), is(equalTo("PONG")));
|
||||
assertThat(connection.info().getProperty("role"), is(equalTo("slave")));
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-580
|
||||
public void factoryUsesMasterSlaveConnections() {
|
||||
|
||||
LettuceClientConfiguration configuration = LettuceTestClientConfiguration.builder().readFrom(ReadFrom.SLAVE)
|
||||
.build();
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(SettingsUtils.standaloneConfiguration(),
|
||||
configuration);
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
RedisConnection connection = factory.getConnection();
|
||||
|
||||
try {
|
||||
assertThat(connection.ping(), is(equalTo("PONG")));
|
||||
assertThat(connection.info().getProperty("role"), is(equalTo("slave")));
|
||||
} finally {
|
||||
this.connection.close();
|
||||
}
|
||||
|
||||
factory.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ package org.springframework.data.redis.test.util;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.rules.ExternalResource;
|
||||
import org.junit.rules.TestRule;
|
||||
@@ -24,8 +26,6 @@ import org.springframework.data.redis.connection.RedisClusterConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisNode;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConverters;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
/**
|
||||
* Simple {@link TestRule} implementation that check Redis is running in cluster mode.
|
||||
*
|
||||
@@ -59,7 +59,7 @@ public class RedisClusterRule extends ExternalResource {
|
||||
* @see org.junit.rules.ExternalResource#before()
|
||||
*/
|
||||
@Override
|
||||
protected void before() throws Throwable {
|
||||
public void before() {
|
||||
Assume.assumeThat(mode, is("cluster"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user