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 節點集合,從中獲取 主節點 的信息。
三、Docker部署圖
我們在測試的時候,將進行3個sentinel和3個redis實例,redis實例為1主2從。
部署實例
具體部署成功后,如下圖所示:
部署完成后實例
四、docker部署過程
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會自動找到配置
發現配置文件多了東西。
五、springboot配置及運行
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
返回
設置一個值入去,就可以查到。