redis的主从模式,如果主机挂掉,要手动切换及修改链接,这种操作在生产环境上基本是不可能,一般都会中断服务,然后再通过重启来完成。但在redis 2.8之后可以用哨兵模式来解决这个问题。
哨兵网络图
sentinel是redis高可用的解决方案,sentinel系统(N个sentinel实例,N >= 1)可以监视一个或者多个redis master服务,以及这些master服务的所有从服务;当某个master服务下线时,自动将该master下的某个从服务升级为master服务替代已下线的master服务继续处理请求。
sentine哨兵l本质上是一个特殊的redis服务,所以初始化的时候跟redis服务初始化差不多,不过有几点不一样;首先sentinel不会载入RDB或者AOF文件,因为sentinel根本不使用数据库,其次,sentinel不能使用数据库键值对方面的命令,例如set、del、flushdb等等,同时,sentinel也不能使用事务、脚本、RDB或者AOF持久化命令,最后,复制命令,发布与订阅命令,文件事件处理器,时间事件处理器等只能在sentinel内部使用。
Redis 的 Sentinel 的最小配置是一主一从。Sentinel 的主要功能包括主节点存活检测、主从运行情况检测、自动故障转移 (failover)、主从切换。
1、监控
Sentinel 会不断的检查 主服务器 和 从服务器 是否正常运行。
2、通知
当被监控的某个 Redis 服务器出现问题,Sentinel 通过 API 脚本 向 管理员 或者其他的 应用程序 发送通知。
3、自动故障转移
当 主节点 不能正常工作时,Sentinel 会开始一次 自动的 故障转移操作,它会将与 失效主节点 是 主从关系 的其中一个 从节点 升级为新的 主节点,并且将其他的 从节点 指向 新的主节点。
4、配置提供者
在 Redis Sentinel 模式下,客户端应用 在初始化时连接的是 Sentinel 节点集合,从中获取 主节点 的信息。
我们在测试的时候,将进行3个sentinel和3个redis实例,redis实例为1主2从。
部署实例
具体部署成功后,如下图所示:
部署完成后实例
1、环境准备
在主机上安装好docker,本实例机器ip为:192.168.197.24,redis的版本为:3.2
各redis的ip和端口如下:
redis主节点:p:6379
redis从节点:ip:6380,ip:6381
sentinel:ip:26379,ip:26380,ip:26381
2、部署主从redis
如果网卡不存在先创建网卡 docker network create --gateway 172.18.0.1 --subnet 172.18.0.0/16 host (host一般会存在)
执行下面命令创建redis实例:
sudo docker run --name redis6379 --net=host -v $PWD/data6379:/data -d redis:3.2 redis-server --port 6379 --slave-read-only no
sudo docker run --name redis6380 --net=host -v $PWD/data6380:/data -d redis:3.2 redis-server --slaveof 192.168.197.24 6379 --port 6380 --slave-read-only no
sudo docker run --name redis6381 --net=host -v $PWD/data6381:/data -d redis:3.2 redis-server --slaveof 192.168.197.24 6379 --port 6381 --slave-read-only no
注意添加:--slave-read-only no
否则会出现下面错误:
READONLY You can't write against a read only slave.
3、执行命名查看redis 同步情况
docker logs redis6379
docker logs redis6380
docker logs redis6381
日志
4、部署sentinel
新建文件 sentinel-26379.conf、sentinel-26380.conf、sentinel-26381.conf
protected-mode no
bind 0.0.0.0
port 26379
daemonize yes
sentinel monitor mymaster 192.168.2.139 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
logfile "/var/log/redis/redis.log"
protected-mode no
bind 0.0.0.0
port 26380
daemonize yes
sentinel monitor mymaster 192.168.197.24 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
logfile "/var/log/redis/redis.log"
protected-mode no
bind 0.0.0.0
port 26381
daemonize yes
sentinel monitor mymaster 192.168.197.24 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
logfile "/var/log/redis/redis.log"
如下:
sentinel配置文件
5、启动3台sentinel命令:
sentinel1
先:sudo docker run -it --name sentinel-26379 --net=host -v $PWD/sentinel-26379.conf:/usr/local/etc/redis/sentinel.conf -d redis:3.2 /bin/bash
再:sudo docker exec -it sentinel-26379 /bin/bash
最后在容器里设置激活哨兵模式:redis-sentinel /usr/local/etc/redis/sentinel.conf
sentinel2
先:sudo docker run -it --name sentinel-26380 --net=host -v $PWD/sentinel-26380.conf:/usr/local/etc/redis/sentinel.conf -d redis:3.2 /bin/bash
再:sudo docker exec -it sentinel-26380 /bin/bash
最后在容器里设置激活哨兵模式:redis-sentinel /usr/local/etc/redis/sentinel.conf
sentinel3
先:sudo docker run -it --name sentinel-26381 --net=host -v $PWD/sentinel-26381.conf:/usr/local/etc/redis/sentinel.conf -d redis:3.2 /bin/bash
再:sudo docker exec -it sentinel-26381 /bin/bash
最后在容器里设置激活哨兵模式:redis-sentinel /usr/local/etc/redis/sentinel.conf
6、sentenel会根据master的数据自动把其他salve和sentenel找出来写到自己的配置文件
查看配置文件cat sentinel-26379.conf
sentinel会自动找到配置
发现配置文件多了东西。
1、新建springboot项目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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.eujian</groupId>
<artifactId>redis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>redis</name>
<description>Demo project for Spring Boot</description>
<properties>
<JAVA.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、配置文件配置redis的方式
spring.redis.sentinel.master=mymaster
spring.redis.sentinel.nodes=192.168.197.24:26379,192.168.197.24:26380,192.168.197.24:26381
3、创建类用于访问
@RequestMApping
@RestController
public class Controller {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@GetMapping("getkey")
public String getkey(String key){
String result = stringRedisTemplate.opsForValue().get(key);
return result;
}
@GetMapping("setkey")
public void setkey(String key, String value){
stringRedisTemplate.opsForValue().set(key, value);
}
}
}
4、具体的代码目录为
springboot项目代码
启动springboot项目,即可以访问:
1、设置redis值:
http://localhost:8080/setkey?key=aa&value=789
2、查询redis值:
http://localhost:8080/getkey?key=aa
返回
设置一个值入去,就可以查到。