1. 程式人生 > >springboot中配置主從redis

springboot中配置主從redis

oca 配置文件 ping bean gap ons ng- class 如果

測試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

技術分享

結果

技術分享

springboot中配置主從redis