导航:
环境:
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
重启执行结果
与终端执行结果一致,均不允许写!
【补充】
需要注意的事儿~
主从配置需要确保cluster-enabled=no或者保持注释状态
主从模式下slave服务需要正确配置master的密码
主从间网络保持畅通(可达性及防火墙限制)