Purpose
In this article , I will demo how to connect to multiple(for example 2) redis server using spring boot app. Just as following picture shows.
Environment
Spring boot 1.x+
Jdk 8+
Redis
The Project Layout
The layout of this demo project is as follows, all the example code can be found here :
➜ spring-boot-multiredis git: ( master ) tree .
│ │ │ ├── MultiRedisApplication.java
│ │ │ │ ├── Redis1Configuration.java
│ │ │ │ ├── Redis1Property.java
│ │ │ │ ├── Redis2Configuration.java
│ │ │ │ ├── Redis2Property.java
│ │ │ │ └── RedisCommonProperty.java
│ │ │ ├── MultiRedisTestRunner.java
│ │ │ └── MyMessageReceiver.java
│ │ └── application.properties
The Pom
We use maven to define the dependencies:
< project.build.sourceEncoding > UTF-8 </ project.build.sourceEncoding >
< java.version > 1.8 </ java.version >
< start-class > Application </ start-class >
<!-- Import dependency management from Spring Boot -->
< groupId > org.springframework.boot </ groupId >
< artifactId > spring-boot-dependencies </ artifactId >
< version > 1.4.3.RELEASE </ version >
< artifactId > spring-boot-multiredis </ artifactId >
< groupId > org.springframework.boot </ groupId >
< artifactId > spring-boot-starter-data-redis </ artifactId >
< groupId > com.fasterxml.jackson.core </ groupId >
< artifactId > jackson-databind </ artifactId >
The code
1. Config file: src/main/resources/application.properties
spring.redis.host =localhost
spring.redis2.host =localhost
Here we define two redis connection, one is localhost:6379, the other is localhost:26379
2. Property config classes: src/main/java/com.bswen.sbmr/config/
To read the above properties file into spring boot, we must define configuration classes:
At first, we define a common class as the base class of redis configuration classes:
public class RedisCommonProperty {
Then, we define Redis1Property and Redis2Property class to denote the different redis configurations
Redis1Property.java
@ ConfigurationProperties ( prefix = " spring.redis " )
public class Redis1Property extends RedisCommonProperty {
Redis2Property.java
@ ConfigurationProperties ( prefix = " spring.redis2 " )
public class Redis2Property extends RedisCommonProperty {
Pay attention to the ConfigurationProperties annotation, we use it to load different properties from the application.properties file.
Thirdly, we should define how to get the RedisTemplate and RedisConnectionFactory from above properties:
For redis server1, we define Redis1Configuration :
public class Redis1Configuration {
private Redis1Property redis1Property ;
@ Bean ( name = " redis1ConnectionFactory " )
public RedisConnectionFactory userRedisConnectionFactory () {
JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory () ;
redisConnectionFactory . setHostName ( redis1Property . getHost ()) ;
redisConnectionFactory . setPort ( redis1Property . getPort ()) ;
redisConnectionFactory . setDatabase ( redis1Property . getDatabase ()) ;
redisConnectionFactory . setPoolConfig ( getPoolConfig ()) ;
return redisConnectionFactory;
private JedisPoolConfig getPoolConfig () {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig () ;
jedisPoolConfig . setMaxIdle ( 8 ) ;
jedisPoolConfig . setMinIdle ( 1 ) ;
jedisPoolConfig . setMaxTotal ( 8 ) ;
@ Bean ( name = " redis1StringRedisTemplate " )
public StringRedisTemplate userStringRedisTemplate ( @ Qualifier ( " redis1ConnectionFactory " ) RedisConnectionFactory cf ) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate () ;
stringRedisTemplate . setConnectionFactory ( cf ) ;
return stringRedisTemplate;
@ Bean ( name = " redis1RedisTemplate " )
public RedisTemplate userRedisTemplate ( @ Qualifier ( " redis1ConnectionFactory " ) RedisConnectionFactory cf ) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate () ;
stringRedisTemplate . setConnectionFactory ( cf ) ;
//setSerializer(stringRedisTemplate);
return stringRedisTemplate;
For redis server2, we define Redis2Configuration :
public class Redis2Configuration {
private Redis2Property redis2Property ;
private JedisPoolConfig getPoolConfig () {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig () ;
jedisPoolConfig . setMaxIdle ( 8 ) ;
jedisPoolConfig . setMinIdle ( 1 ) ;
jedisPoolConfig . setMaxTotal ( 8 ) ;
@ Bean ( name = " redis2ConnectionFactory " )
public RedisConnectionFactory roleRedisConnectionFactory () {
JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory () ;
redisConnectionFactory . setHostName ( redis2Property . getHost ()) ;
redisConnectionFactory . setPort ( redis2Property . getPort ()) ;
redisConnectionFactory . setDatabase ( redis2Property . getDatabase ()) ;
redisConnectionFactory . setPoolConfig ( getPoolConfig ()) ;
return redisConnectionFactory;
@ Bean ( name = " redis2StringRedisTemplate " )
public StringRedisTemplate roleStringRedisTemplate ( @ Qualifier ( " redis2ConnectionFactory " ) RedisConnectionFactory cf ) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate () ;
stringRedisTemplate . setConnectionFactory ( cf ) ;
return stringRedisTemplate;
@ Bean ( name = " redis2RedisTemplate " )
public RedisTemplate roleRedisTemplate ( @ Qualifier ( " redis2ConnectionFactory " ) RedisConnectionFactory cf ) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate () ;
stringRedisTemplate . setConnectionFactory ( cf ) ;
//setSerializer(stringRedisTemplate);
return stringRedisTemplate;
Now we have setup the properties and the configurations , we have beans of RedisTemplate , we can test it as follows:
public class MultiRedisTestRunner implements CommandLineRunner {
private final static Logger logger = LoggerFactory . getLogger ( MultiRedisApplication . class ) ;
@ Qualifier ( " redis1StringRedisTemplate " )
private StringRedisTemplate userStringRedisTemplate ;
@ Qualifier ( " redis2StringRedisTemplate " )
private StringRedisTemplate roleStringRedisTemplate ;
public void run ( String ... strings ) throws Exception {
for ( int i = 0 ; i < 10 ; i ++ ) {
logger . info ( " ===================================================================== " ) ;
logger . info ( " start loop " + i ) ;
userStringRedisTemplate . opsForValue () . set ( key, " value " + i ) ;
roleStringRedisTemplate . opsForValue () . set ( key, " value " + (i + 1 ) ) ;
String primaryKeyValue = userStringRedisTemplate . opsForValue () . get ( key ) ;
String secondaryKeyValue = roleStringRedisTemplate . opsForValue () . get ( key ) ;
logger . info ( " ===================================================================== " ) ;
logger . info ( String . format ( " read from the redis1, key %s value is %s " , key, primaryKeyValue )) ;
logger . info ( String . format ( " read from the redis2, key %s value is %s " , key, secondaryKeyValue )) ;
Run it, we get this result:
3-05 17:26:49.352 INFO 13130 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647
2021-03-05 17:26:49.481 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.482 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : start loop 0
2021-03-05 17:26:49.507 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.507 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis1, key key0 value is value0
2021-03-05 17:26:49.507 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis2, key key0 value is value1
2021-03-05 17:26:49.507 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.507 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : start loop 1
2021-03-05 17:26:49.511 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.511 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis1, key key1 value is value1
2021-03-05 17:26:49.511 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis2, key key1 value is value2
2021-03-05 17:26:49.511 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.512 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : start loop 2
2021-03-05 17:26:49.515 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.516 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis1, key key2 value is value2
2021-03-05 17:26:49.516 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis2, key key2 value is value3
2021-03-05 17:26:49.516 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.516 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : start loop 3
2021-03-05 17:26:49.520 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.520 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis1, key key3 value is value3
2021-03-05 17:26:49.520 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis2, key key3 value is value4
2021-03-05 17:26:49.520 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.520 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : start loop 4
2021-03-05 17:26:49.524 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.524 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis1, key key4 value is value4
2021-03-05 17:26:49.524 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis2, key key4 value is value5
2021-03-05 17:26:49.524 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.524 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : start loop 5
2021-03-05 17:26:49.528 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.529 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis1, key key5 value is value5
2021-03-05 17:26:49.529 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis2, key key5 value is value6
2021-03-05 17:26:49.529 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.529 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : start loop 6
2021-03-05 17:26:49.533 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.533 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis1, key key6 value is value6
2021-03-05 17:26:49.533 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis2, key key6 value is value7
2021-03-05 17:26:49.533 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.533 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : start loop 7
2021-03-05 17:26:49.538 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.538 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis1, key key7 value is value7
2021-03-05 17:26:49.538 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis2, key key7 value is value8
2021-03-05 17:26:49.538 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.538 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : start loop 8
2021-03-05 17:26:49.542 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.542 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis1, key key8 value is value8
2021-03-05 17:26:49.542 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis2, key key8 value is value9
2021-03-05 17:26:49.542 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.542 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : start loop 9
2021-03-05 17:26:49.546 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : =====================================================================
2021-03-05 17:26:49.546 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis1, key key9 value is value9
2021-03-05 17:26:49.546 INFO 13130 --- [ main] com.bswen.sbmr.MultiRedisApplication : read from the redis2, key key9 value is value10
It works!
By the way: How to subscribe to two redis server simultaneously?
Now we can connect two redis server , send command (get/set/…) to them and get response, but how can we use the pub/sub functions to listen to redis channels?
As the above picture shown, the process is as follows:
You should have two redis server running
Your spring boot application connects to the two redis servers
Then you can subscribe to topics on the two redis servers by using spring boot RedisMessageListener
At last, the messages would be forwarded to a RedisReceiver to process
So the key point is how to setup two redis servers’ RedisMessageListener, let’s check the code:
public class MultiRedisListenerTester {
RedisMessageListenerContainer container1 ( @ Qualifier ( " redis1ConnectionFactory " ) RedisConnectionFactory connectionFactory ,
MessageListenerAdapter listenerAdapter ) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer () ;
container . setConnectionFactory ( connectionFactory ) ;
container . addMessageListener ( listenerAdapter, new PatternTopic ( " tasks1 " )) ;
RedisMessageListenerContainer container2 ( @ Qualifier ( " redis2ConnectionFactory " ) RedisConnectionFactory connectionFactory ,
MessageListenerAdapter listenerAdapter ) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer () ;
container . setConnectionFactory ( connectionFactory ) ;
container . addMessageListener ( listenerAdapter, new PatternTopic ( " tasks2 " )) ;
MessageListenerAdapter listenerAdapter ( MyMessageReceiver receiver ) {
return new MessageListenerAdapter ( receiver, " receiveMessage " ) ;
Let’s analyze the above code:
We create a class named MultiRedisListenerTester with the annotation @Component, which indicate that the class is a spring bean.
The method named container1 and container2 has two parameters, one is connectionFactory, which is injected with specified redisConnectionFactory with @Qualifer annotation, the redisConnectionFactory beans are defined in Redis1Configuration and Redis2Configuration , the other is a listenerAdapter, which is supplied by listenerAdapter method defined below.
We subscribed with topic name tasks1 on redis server1 and tasks2 on redis server2 .
The method named listenerAdapter indicates that when redis get a message, it would push the message the the receiver’s receiveMessage method.
Now let’s check the reciever’s code:
public class MyMessageReceiver {
private static Log log = LogFactory . getLog ( MyMessageReceiver . class ) ;
public void receiveMessage ( String message ) {
log . info ( " got message " + message ) ;
Let’s test the multiple redis server’s pub/sub feature on redis server1:
//publish on redis server1 with redis-cli console
localhost-6379:0 > publish tasks1 hello1
//got message from spring boot message receiver:
2021-03-06 11:22:31.465 INFO 17414 --- [ container1-2] c.bswen.sbmr.service.MyMessageReceiver : got message hello1
Let’s test the multiple redis server’s pub/sub feature on redis server2:
//publish on redis server2 with redis-cli console
localhost-6379:0 > publish tasks2 hello2
//got message from spring boot message receiver:
2021-03-06 11:22:32.465 INFO 17414 --- [ container1-2] c.bswen.sbmr.service.MyMessageReceiver : got message hello2
If you want to tell from which redis server pushed the message, e.g. the source of the message, you can inject different named MessageListenerAdapter instances by using @Qualifier injection in method container1 and container2 .
For example:
RedisMessageListenerContainer container2 ( @ Qualifier ( " redis2ConnectionFactory " ) RedisConnectionFactory connectionFactory,
@ Qualifier ( " redis2Listener " ) MessageListenerAdapter listenerAdapter ) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer () ;
container . setConnectionFactory ( connectionFactory ) ;
container . addMessageListener ( listenerAdapter, new PatternTopic ( " tasks2 " )) ;
@ Bean ( name = " redis2Listener " )
MessageListenerAdapter listenerAdapter ( MyMessageReceiver receiver ) {
return new MessageListenerAdapter ( receiver, " receiveMessage " ) ;
Summary
In this post, I demonstrated how to connect to multiple redis server instances with spring boot, the key point is that you should setup specific configuration for each redis server connection. And I also showed how to use the pub/sub function of springboot in the multiple redis server environment, thanks for your reading. All code of the project is uploaded to github.com, you can download at this link .
Final Words + More Resources
My intention with this article was to help others who might be considering solving such a problem.
So I hope that’s been the case here. If you still have any questions, don’t hesitate to ask me by
email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by
starring the repo on GitHub !