springboot中配置主从redis

Posted Hendsame

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot中配置主从redis相关的知识,希望对你有一定的参考价值。

测试redis的主从配置

redis实例

文件夹名称如下

redis_master_s
redis_slaver1_s
redis_slaver2_s

redis.conf文件

master的redis.conf文件(其余是默认设置)

1 port 6379
2 daemonize yes
3 # 这个文件夹要改成自己的目录
4 dir "/Users/vobile_lzl/redis_master_s"

slaver1的redis.conf文件

1 port 6378
2 # 主服务器端口为6379
3 slaveof 127.0.0.1 6379
4 dir "/Users/vobile_lzl/redis_slaver1_s"

slaver2的redis.conf文件

1 port 6377
2 # 主服务器端口为6379
3 slaveof 127.0.0.1 6379
4 dir "/Users/vobile_lzl/redis_slaver2_s"

这个主从服务器就配置好了。 
启动服务(命令大致如此)

./redis-server redis.conf

测试一下主从复制的功能 
1. 主服务器写入,从服务器可以读取到 
2. 从服务器不能写入

注意端口,6379表示主服务器,6377、6378是从服务器

127.0.0.1:6379> set name lzl
OK
127.0.0.1:6377> get name
"lzl"
127.0.0.1:6378> get name
"lzl"
# 从服务器不能写入
127.0.0.1:6378> set name lzl
(error) READONLY You can\'t write against a read only slave.
127.0.0.1:6377> set nam fdk
(error) READONLY You can\'t write against a read only slave.

sentinel.conf文件

sentinel是哨兵,用于监视主从服务器的运行状况,如果主服务器挂掉,会在从服务器中选举一个作为主服务器。 
配置文件如下 
master的sentinel.conf

1 port 26379
2 # 初次配置时的状态,这个sentinel会自动更新
3 sentinel monitor mymaster 127.0.0.1 6379 2
4 daemonize yes
5 logfile "./sentinel_log.log"

slaver1的sentinel.conf

1 port 26378
2 # 初次配置时的状态,这个sentinel会自动更新
3 sentinel monitor mymaster 127.0.0.1 6379 2
4 daemonize yes
5 logfile "./sentinel_log.log"

slaver2的sentinel.conf

1 port 26377
2 # 初次配置时的状态,这个sentinel会自动更新
3 sentinel monitor mymaster 127.0.0.1 6379 2
4 daemonize yes
5 logfile "./sentinel_log.log"

再次启动redis所有的服务端

./redis-server redis.conf
./redis-server sentinel.conf --sentinel

分别开启redis的客户端

./redis-cli
./redis-cli -h 127.0.0.1 -p 6378
./redis-cli -h 127.0.0.1 -p 6377

使用一下命令查看三个redis服务的状态

info replication

master 
role:master

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6378,state=online,offset=4102,lag=1
slave1:ip=127.0.0.1,port=6377,state=online,offset=4102,lag=1
master_repl_offset:4102
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:4101

slaver1

127.0.0.1:6378> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:15931
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

slaver2

127.0.0.1:6377> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:21629
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

将master服务杀死

vobile-lzldeMacBook-Pro:~ vobile_lzl$ ps -ef | grep redis
  501 13258     1   0  9:52下午 ??         0:00.37 ./redis-server *:6379 

  kill -9 13258

再次查看master的状态 
说明master已经宕机

127.0.0.1:6379> info replication
Could not connect to Redis at 127.0.0.1:6379: Connection refused

再观察一段时间,6377的从服务器成为主服务器

127.0.0.1:6377> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

恢复主服务器,并设置为master

springboot中配置主从redis

 

 RedisCacheConfig

  1 package com.config;
  2 
  3 import com.fasterxml.jackson.annotation.JsonAutoDetect;
  4 import com.fasterxml.jackson.annotation.PropertyAccessor;
  5 import com.fasterxml.jackson.databind.ObjectMapper;
  6 import org.springframework.beans.factory.annotation.Value;
  7 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
  8 import org.springframework.cache.annotation.CachingConfigurerSupport;
  9 import org.springframework.cache.annotation.EnableCaching;
 10 import org.springframework.cache.interceptor.KeyGenerator;
 11 import org.springframework.context.annotation.Bean;
 12 import org.springframework.context.annotation.Configuration;
 13 import org.springframework.data.redis.cache.RedisCacheManager;
 14 import org.springframework.data.redis.connection.RedisNode;
 15 import org.springframework.data.redis.connection.RedisSentinelConfiguration;
 16 import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
 17 import org.springframework.data.redis.core.RedisTemplate;
 18 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
 19 import org.springframework.data.redis.serializer.StringRedisSerializer;
 20 
 21 import java.lang.reflect.Method;
 22 
 23 /**
 24  * @author zhujinmin6
 25  */
 26 @Configuration
 27 @EnableAutoConfiguration
 28 @EnableCaching //加上这个注解是的支持缓存注解
 29 public class RedisCacheConfig extends CachingConfigurerSupport {
 30 
 31     @Value("${spring.redis.host}")
 32     private String host;
 33 
 34     @Value("${spring.redis.port}")
 35     private int port;
 36 
 37     @Value("${spring.redis.timeout}")
 38     private int timeout;
 39 
 40     @Value("${spring.redis.database}")
 41     private int database;
 42 
 43     @Value("${spring.redis.password}")
 44     private String password;
 45 
 46     @Value("${spring.redis.sentinel.nodes}")
 47     private String redisNodes;
 48 
 49     @Value("${spring.redis.sentinel.master}")
 50     private String master;
 51 
 52 
 53     /**
 54      * redis哨兵配置
 55      * @return
 56      */
 57     @Bean
 58     public RedisSentinelConfiguration redisSentinelConfiguration(){
 59         RedisSentinelConfiguration configuration = new RedisSentinelConfiguration();
 60         String[] host = redisNodes.split(",");
 61         for(String redisHost : host){
 62             String[] item = redisHost.split(":");
 63             String ip = item[0];
 64             String port = item[1];
 65             configuration.addSentinel(new RedisNode(ip, Integer.parseInt(port)));
 66         }
 67         configuration.setMaster(master);
 68         return configuration;
 69     }
 70 
 71     /**
 72      * 连接redis的工厂类
 73      *
 74      * @return
 75      */
 76     @Bean
 77     public JedisConnectionFactory jedisConnectionFactory() {
 78         JedisConnectionFactory factory = new JedisConnectionFactory(redisSentinelConfiguration());
 79         factory.setHostName(host);
 80         factory.setPort(port);
 81         factory.setTimeout(timeout);
 82         factory.setPassword(password);
 83         factory.setDatabase(database);
 84         return factory;
 85     }
 86 
 87     /**
 88      * 配置RedisTemplate
 89      * 设置添加序列化器
 90      * key 使用string序列化器
 91      * value 使用Json序列化器
 92      * 还有一种简答的设置方式,改变defaultSerializer对象的实现。
 93      *
 94      * @return
 95      */
 96     @Bean
 97     public RedisTemplate<Object, Object> redisTemplate() {
 98         //StringRedisTemplate的构造方法中默认设置了stringSerializer
 99         RedisTemplate<Object, Object> template = new RedisTemplate<>();
100         //设置开启事务
101         template.setEnableTransactionSupport(true);
102         //set key serializer
103         StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
104         template.setKeySerializer(stringRedisSerializer);
105         template.setHashKeySerializer(stringRedisSerializer);
106 
107         template.setConnectionFactory(jedisConnectionFactory());
108         template.afterPropertiesSet();
109         return template;
110     }
111 
112     /**
113      * 设置RedisCacheManager
114      * 使用cache注解管理redis缓存
115      *
116      * @return
117      */
118     @Override
119     @Bean
120     public RedisCacheManager cacheManager() {
121         RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate());
122         return redisCacheManager;
123     }
124 
125     /**
126      * 自定义生成redis-key
127      *
128      * @return
129      */
130     @Override
131     public KeyGenerator keyGenerator() {
132         return new KeyGenerator() {
133             @Override
134             public Object generate(Object o, Method method, Object... objects) {
135                 StringBuilder sb = new StringBuilder();
136                 sb.append(o.getClass().getName()).append(".");
137                 sb.append(method.getName()).append(".");
138                 for (Object obj : objects) {
139                     sb.append(obj.toString());
140                 }
141                 System.out.println("keyGenerator=" + sb.toString());
142                 return sb.toString();
143             }
144         };
145     }
146 }

 

SampleController

package com.controller;

import com.dao.UseRedisDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author zhujinming6
 * @create 2017-10-24 9:25
 **/
@RestController
@RequestMapping("/sample")
public class SampleController {

    @Autowired
    private UseRedisDao useRedisDao;

    @RequestMapping("/hi")
    public String sayHello(String key,String value){
        useRedisDao.setValue(key,value);
        return useRedisDao.getValue(key);
    }
}

UseRedisDao

package com.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;

import javax.annotation.PostConstruct;
import java.util.Map;


/**
 * @Author: zhujinmin6
 * @Date: create in 15:44 17/9/21.
 * @description:整合redis的实例,简单了解RedisTemplate的API
 */
@Repository
public class UseRedisDao {

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;
    private ValueOperations<Object,Object> valueOperations;
    private ListOperations<Object,Object> listOperations;
    private HashOperations hashOperations;

    @PostConstruct
    public void getValueOperation(){
        valueOperations = redisTemplate.opsForValue();
        listOperations = redisTemplate.opsForList();
        hashOperations = redisTemplate.opsForHash();
    }

    public void setValue(String key, String value){
        valueOperations.set(key, value);
    }

    public String getValue(String key){
        return (String) valueOperations.get(key);
    }

    public void addList(String key, String value){
        listOperations.leftPush(key, value);
    }
    public Long getListSize(String key){
        return listOperations.size(key);
    }

    public void setHashMap(String key, Map map){
        hashOperations.putAll(key, map);
    }
    public Map getHashMap(String key){
        return hashOperations.entries(key);
    }
}

Application

package com;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.ImportResource;

/**
 * Web容器启动主类
 * @author zhujinmin6
 */
@SpringBootApplication(scanBasePackages = { "com" })
@EnableAutoConfiguration
@ServletComponentScan
public class Application extends  SpringBootServletInitializer {


    public static void main(String [] args){
        SpringApplication.run(Application.class,args);
    }


    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>redis_clu</groupId>
    <artifactId>redis_clu</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        </dependency>
        <!-- spring boot and redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>1.5.7.RELEASE</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

application.properties

#springSession \\u9009\\u62E9\\u540C\\u6B65session\\u7684\\u5916\\u90E8\\u7F13\\u5B58
#spring.session.store-type=redis

#========================redis \\u914D\\u7F6E=============================
# Redis\\u6570\\u636E\\u5E93\\u7D22\\u5F15\\uFF08\\u9ED8\\u8BA4\\u4E3A0\\uFF09,\\u5982\\u679C\\u8BBE\\u7F6E\\u4E3A1\\uFF0C\\u90A3\\u4E48\\u5B58\\u5165\\u7684key-value\\u90FD\\u5B58\\u653E\\u5728select 1\\u4E2D
spring.redis.database=0 
# Redis\\u670D\\u52A1\\u5668\\u5730\\u5740
spring.redis.host=localhost
# Redis\\u670D\\u52A1\\u5668\\u8FDE\\u63A5\\u7AEF\\u53E3
spring.redis.port=6379 
# Redis\\u670D\\u52A1\\u5668\\u8FDE\\u63A5\\u5BC6\\u7801\\uFF08\\u9ED8\\u8BA4\\u4E3A\\u7A7A\\uFF09
spring.redis.password=
#\\u8FDE\\u63A5\\u6C60\\u6700\\u5927\\u8FDE\\u63A5\\u6570\\uFF08\\u4F7F\\u7528\\u8D1F\\u503C\\u8868\\u793A\\u6CA1\\u6709\\u9650\\u5236\\uFF09
spring.redis.pool.max-active=8 
# \\u8FDE\\u63A5\\u6C60\\u6700\\u5927\\u963B\\u585E\\u7B49\\u5F85\\u65F6\\u95F4\\uFF08\\u4F7F\\u7528\\u8D1F\\u503C\\u8868\\u793A\\u6CA1\\u6709\\u9650\\u5236\\uFF09
spring.redis.pool.max-wait=-1 
# \\u8FDE\\u63A5\\u6C60\\u4E2D\\u7684\\u6700\\u5927\\u7A7A\\u95F2\\u8FDE\\u63A5
spring.redis.pool.max-idle=8 
# \\u8FDE\\u63A5\\u6C60\\u4E2D\\u7684\\u6700\\u5C0F\\u7A7A\\u95F2\\u8FDE\\u63A5
spring.redis.pool.min-idle=0 
# \\u8FDE\\u63A5\\u8D85\\u65F6\\u65F6\\u95F4\\uFF08\\u6BEB\\u79D2\\uFF09
spring.redis.timeout=0
### \\u4E3B\\u4ECE\\u914D\\u7F6E
# name of Redis server  \\u54E8\\u5175\\u76D1\\u542C\\u7684Redis server\\u7684\\u540D\\u79F0
spring.redis.sentinel.master=mymaster
# comma-separated list of host:port pairs  \\u54E8\\u5175\\u7684\\u914D\\u7F6E\\u5217\\u8868
spring.redis.sentinel.nodes=127.0.0.1:26379,127.0.0.1:26378,127.0.0.1:26377

 

启动成功

调用redis

结果

 

 博主开源项目:https://github.com/Enast/hummer,走过路过,请点个赞

以上是关于springboot中配置主从redis的主要内容,如果未能解决你的问题,请参考以下文章

Redis分片主从哨兵集群,原理详解,集群的配置安装,8大数据类型,springboot整合使用

java架构之路-(Redis专题)SpringBoot连接Redis超简单

Redis# 常见报错Unsatisfied dependency设置密码主从配置

SpringBoot集成Redis并实现主从架构

SpringBoot集成Redis并实现主从架构

SpringBoot集成Redis并实现主从架构