Redis集羣部署及Springboot架構下應用(主從集羣模式)

導航:

主從集羣
哨兵集羣
分區集羣

環境:

redis:5.0.8
Springboot: 2.2.3.RELEASE
redis安裝參見:CentOS7下安裝Redis(單機版)

集羣方式及配置

基礎配置集羣配置:

#後臺運行(守護進程)
daemonize yes 
#去除保護模式(允許遠程訪問)
protected-mode no
#去除綁定(遠程訪問)
#bind 127.0.0.1
# 設置密碼
requirepass redispwd

本次配置基於同一機器不通端口做集羣,當redis位於不同機器時,部分配置可以省去(以下配置過程中會說明/【單機非必須】:當前機器僅運行一個redis實例)

主從集羣

主從集羣表現形式爲一主多從,主負責寫和讀,從只負責寫。
修改主節點配置

拷貝一份配置文件命名爲redis-master.conf(來源安裝目錄:redis-5.0.8/redis.conf)

# db寫入磁盤目錄位置(文件夾路徑如果不存在,需要手動創建):【單機非必須】
dir ./master 
#日誌目錄,默認運行命令時的目錄【單機非必須】
logfile "./master/master.log"
#pid寫入位置,默認/var/run/redis_6379.pid【單機非必須】
pidfile "/var/run/redis_6379.pid"

修改叢點1配置 6380節點
拷貝redis-master.conf 命名爲redis-slave6380.conf

# redis端口【單機非必須】
port 6380
 # db寫入磁盤目錄位置(文件夾路徑如果不存在,需要手動創建):【單機非必須】
dir ./slave/6380 
#日誌目錄,默認運行命令時的目錄【單機非必須】
logfile "./slave/slave6380.log"
#pid寫入位置,默認/var/run/redis_6379.pid【單機非必須】
pidfile /var/run/redis_6380.pid

#----以下爲叢節點的不同修改點

#主節點地址(ip 端口)
slaveof 192.168.1.17 6379
#master節點密碼 ,(打開註釋,修改master的密碼即可)
masterauth redispwd

修改叢點2配置 6381節點
拷貝redis-slave6380.conf 命名爲redis-slave6381.conf

# redis端口【單機非必須】
port 6381
 # db寫入磁盤目錄位置(文件夾路徑如果不存在,需要手動創建):【單機非必須】
dir ./slave/6381 
#日誌目錄,默認運行命令時的目錄【單機非必須】
logfile "./slave/slave6381.log"
#pid寫入位置,默認/var/run/redis_6379.pid【單機非必須】
pidfile /var/run/redis_6381.pid

#----以下爲叢節點的不同修改點(因爲當前節點是叢節點1複製過來的,所以以下信息無需修改)

#主節點地址(ip 端口)
slaveof 192.168.1.17 6379
#master節點密碼 ,(打開註釋,修改master的密碼即可)
masterauth redispwd

啓動主、叢節點配置
在這裏插入圖片描述

#注意redis-server路徑及配置文件路徑
 ./bin/redis-server redis-master.conf
 ./bin/redis-server redis-slave6380.conf
  ./bin/redis-server redis-slave6381.conf

查看master節點

#登陸master節點,執行info命令查看主從節點信息
info

叢節點已經顯示
#登陸6380叢節點,執行info看一下主節點信息已顯示

分別登陸叢節點,感受一下主從同步

[root@bogon bin]# ./redis-cli -p 6380
[root@bogon bin]# ./redis-cli -p 6381

master節點設置一個值

#master 節點設置
 set testkey demo

在這裏插入圖片描述
slave節點查看緩存

#slave節點查詢master緩存
get testkey

slave6380節點
在這裏插入圖片描述
slave6381節點
在這裏插入圖片描述
slave節點不允許寫入
在這裏插入圖片描述

主從集羣在Springboot中的配置

主從配置在Springboot中配置跟單機部署差不多,需要注意的是主/叢節點在使用的時候需要明確知道避免叢節點無法寫入的異常,也正因此主從配置在實際應用中並不多見(當然主節點掛掉導致無法更新緩存也是其中一個原因)。
** 1. pom引入**

        <!-- springboot整合redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2.yml配置(properties配置文件類型自行轉換)

spring:
  redis:
    # Redis服務器地址 單機模式
    host: 192.168.1.17
    # Redis服務器連接端口(這裏配置的是主節點,可以寫,可以讀)
    port: 6379
    # Redis服務器連接密碼(默認爲空)
    password: redispwd
    #jedis連接池信息僅供參考
    jedis:
      pool:
        #連接池最大連接數(使用負值表示沒有限制)
        max-active: 8
        # 連接池最大阻塞等待時間(使用負值表示沒有限制)
        max-wait: -1
        # 連接池中的最大空閒連接
        pool.max-idle: 8
        # 連接池中的最小空閒連接
        pool.min-idle: 0

3.封裝RedisTemplate MyRedisConfig.java


import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@EnableCaching
public class MyRedisConfig {
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 使用Jackson2JsonRedisSerialize 替換默認的jdkSerializeable序列化
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        // 設置value的序列化規則和 key的序列化規則
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
    /**
     * 對redis字符串類型數據操作
     *
     * @param stringRedisTemplate
     * @return
     */
    @Bean({"valueoperations"})
    public ValueOperations<String, String> valueOperations(StringRedisTemplate stringRedisTemplate) {
        return stringRedisTemplate.opsForValue();
    }
}

4.測試Controller SysController.java


import com.platform.test.common.exception.BusinessException;
import com.platform.test.service.SysService;
import com.platform.test.vo.BaseRespVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/sys")
public class SysController {
    static final Logger logger = LoggerFactory.getLogger(SysController.class);
    @Autowired
    @Qualifier("valueoperations")
    ValueOperations<String, String> valueOperations;
    @Autowired
    RedisTemplate<Object,Object> redisTemplate;
    @Autowired
    SysService sysService;
    final static String REDIS_TEST_KEY_VALUE = "__REDIS_TEST_KEY_VALUE";
    
    @RequestMapping("/health")
    public BaseRespVo health(HttpSession session) throws BusinessException {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        HashMap<String, Object> data = new HashMap<>();
        data.put("time-server",sf.format(new Date()));
        data.put("status-redis",checkRedis());
        return new BaseRespVo(data);
    }
   
    private boolean checkRedis() {
        long time = System.currentTimeMillis();
        if(valueOperations == null){
            return false;
        }
        try {
            valueOperations.set(REDIS_TEST_KEY_VALUE+time,REDIS_TEST_KEY_VALUE,300, TimeUnit.MILLISECONDS);
            logger.info("寫入redis key: "+ REDIS_TEST_KEY_VALUE+time +" value:"+REDIS_TEST_KEY_VALUE);
            Thread.sleep(100);
            String value = valueOperations.get(REDIS_TEST_KEY_VALUE+time);
            if (value!=null && REDIS_TEST_KEY_VALUE.equals(value)) {
                logger.info("讀取redis key: "+ REDIS_TEST_KEY_VALUE+time +" value:"+value);
                return true;
            }
        }catch (Exception e){
            logger.error("redis test exception!",e);
        }
        return false;
    }
}

執行結果:
在這裏插入圖片描述
slave節點
在這裏插入圖片描述

5.yml配置切slave節點(properties配置文件類型自行轉換)

spring:
  redis:
    # Redis服務器地址 單機模式
    host: 192.168.1.17
    # Redis服務器連接端口(這裏該配置爲叢節點,不可以寫,但可以讀) 如果叢節點部署到不同的機器上記得同步修改上面的host
    port: 6380

重啓執行結果
在這裏插入圖片描述
與終端執行結果一致,均不允許寫!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章