docker 172.18.1.1 $> redis-cli --cluster create --cluster-replicas 0 172.18.1.1:6379 172.18.1.2:6379 172.18.1.3:6379
They are works well!!
$> redis-cli -c
127.0.0.1:6379> set hello redis
OK
127.0.0.1:6379> get hello
"redis"
127.0.0.1:6379>
spring.redis.cluster.nodes=127.0.0.1:36379,127.0.0.1:36380,127.0.0.1:36381
spring.redis.cluster.max-redirects=6
@Component
@ConfigurationProperties(prefix = "spring.redis.cluster")
public class RedisClusterConfigurationProperties {
List<String> nodes;
public List<String> getNodes() {
return nodes;
}
public void setNodes(List<String> nodes) {
this.nodes = nodes;
}
}
@Configuration
@Service
public class SomesService {
@Autowired
private RedisClusterConfigurationProperties clusterProperties;
@Bean
public JedisPoolConfig jedisPoolConfig() {
final JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
return jedisPoolConfig;
}
@Bean(name = "redisTemplate")
public RedisTemplate redisTemplate() {
RedisTemplate redisTemplate = new RedisTemplate();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(connectionFactory());
redisTemplate.setExposeConnection(true);
return redisTemplate;
}
private RedisConnectionFactory connectionFactory() {
final RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration(clusterProperties.getNodes());
final JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(
clusterConfig, jedisPoolConfig());
jedisConnectionFactory.setUsePool(true);
return jedisConnectionFactory;
}
}
result
org.springframework.data.redis.ClusterStateFailureException: Could not retrieve cluster information. CLUSTER NODES returned with error.
- 172.18.1.1:6379 failed: Could not get a resource from the pool
- 172.18.1.2:6379 failed: Could not get a resource from the pool
- 172.18.1.3:6379 failed: Could not get a resource from the pool
at org.springframework.data.redis.connection.jedis.JedisClusterConnection$JedisClusterTopologyProvider.getTopology(JedisClusterConnection.java:4237)
at org.springframework.data.redis.connection.ClusterCommandExecutor.getClusterTopology(ClusterCommandExecutor.java:349)
at org.springframework.data.redis.connection.ClusterCommandExecutor.executeCommandOnAllNodes(ClusterCommandExecutor.java:188)
at org.springframework.data.redis.connection.jedis.JedisClusterConnection.info(JedisClusterConnection.java:3128)
--- removed my package sorry ;-)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
--- removed my package sorry ;-)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
2019-07-23 15:48:01.579 INFO 13741 --- [ Thread-5] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext@305ffe9e: startup date [Tue Jul 23 15:47:42 KST 2019]; root of context hierarchy
2019:07:23 15:48:01.579 INFO --- [Thread-5] o.s.w.c.s.GenericWebApplicationContext : - 984 Closing org.springframework.web.context.support.GenericWebApplicationContext@305ffe9e: startup date [Tue Jul 23 15:47:42 KST 2019]; root of context hierarchy
Process finished with exit code 255
Could not retrieve cluster information. CLUSTER NODES returned with error.
- 172.18.1.1:6379 failed: Could not get a resource from the pool
* '172.18.1.1' is docker host ip.
* '127.0.0.1:36379' is the value of what I put in application.properties file.
The problem is that in Redis Cluster, clients gets the URLs of all Redis nodes from Redis node itself.
So in your case, the Spring Boot application sends "cluster nodes" request to one of the configured nodes (127.0.0.1:36379,127.0.0.1:36380,127.0.0.1:36381).
As a response, it receives the URL of all Redis nodes and in your case its 172.18.1.1:6379 172.18.1.2:6379 172.18.1.3:6379 and tries to communicate with them. Since this is internal Docker network you get connection failure error.
What you want is to configure each Redis node to have a different "advertised" host and port. This way the clients will receive URL that they can access instead of the internal host and port.
This is the configuration parameters you should add:
cluster-announce-ip: The IP address to announce.
cluster-announce-port: The data port to announce.
cluster-announce-bus-port: The cluster bus port to announce.
See this blog post that explain this in more details: https://get-reddie.com/blog/redis4-cluster-docker-compose/