歡迎訪問陳同學博客原文
介紹
Redis 目前被廣泛應用,緩存、限流、PubSub、分佈式鎖、分佈式數據結構等等許多場景都十分實用,Redis 的高可用(High Available) 自然是必不可少。
Redis 單機有單點故障,Master-Slave 無法做自動故障轉移,可以使用官方推薦的 Sentinel 實現Redis高可用方案。
Sentinel 負責監控 Redis Master,同時 Sentinel 集羣之間通過 Master 進行通訊。Sentinel 以集羣保障自身的可靠性,官方建議 Sentinel 至少保持3個節點。
Sentinel 提供以下特性(來自官網):
- 監控(Monitoring):持續檢查 master、slave 健康狀況
- 提醒(Notification):當Redis實例出問題時,可以通過系統管理員或以API形式通知其他應用。
- 自動故障轉移(Automatic failover):當master發生故障時,Sentinel 會開啓故障處理流程,將一個slave晉升爲master,並將其他slave重新配置到新的master。當應用進行連接時,Sentinel會將新的master告知應用。
- 配置提供者(Configuration provider):Sentinel 爲客戶端提供master節點的地址,當發生故障時,負責報告新的master節點給客戶端。
Sentinel HA 搭建
實驗環境:CentOS 7、Docker 1.13.1
搭建Redis Master-Slave
運行3個redis實例,設置一主兩從。
docker run -it --name redis-master -d redis redis-server
docker run -it --name redis-slave1 -d redis redis-server
docker run -it --name redis-slave2 -d redis redis-server
使用下面命令拿到 redis-master 的IP: 172.17.0.4
docker inspect --format='{{.NetworkSettings.IPAddress}}' redis-master
爲兩個slave節點分別執行下面命令,將自己設置爲slave.
docker exec -it redis-slave1 redis-cli -p 6379
127.0.0.1:6379> slaveof 172.17.0.4 6379
服從複製已搭建好,可以在master看看主從複製的狀態,此時已經檢測到兩個連接上來的slave.
docker exec -it redis-master redis-cli -p 6379
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.17.0.5,port=6379,state=online,offset=546,lag=1
slave1:ip=172.17.0.6,port=6379,state=online,offset=546,lag=0
...
在master做增刪改操作後數據會立即同步到2個slave,主從結構可以做讀寫分離,緩解主庫壓力。
搭建Sentinel集羣
準備配置文件
先從官網下載 Sentinel 的demo配置文件。
redis 配置文件改成 redis.conf 即可。
wget http://download.redis.io/redis-stable/sentinel.conf
做如下修改:
- 設置需要監控的master節點信息,格式:sentinel monitor <master-name> <master-redis-ip> <master-redis-port> <quorum>
sentinel monitor mymaster 172.17.0.4 6379 2
如果要監控多個master集羣,這裏可以寫多行,各個集羣的自定義集羣名要修改一下。
quorum 是最小投票數,準備使用3個sentinel節點,設置爲2後選擇新master時需要2個節點同意。
- 設置
daemonize yes
表示以後臺守護程序運行
運行集羣
sentinel.conf 複製三個,分別爲 sentinel1.conf、sentinel2.conf、sentinel3.conf,在啓動時這幾個文件會被自動寫入一些其他配置信息。
先啓動三個redis實例:redis-sentinel1、2、3,由於sentinel會修改sentinel.conf,我的配置文件位於 /root/redis
目錄。
docker run -it --name redis-sentinel1 --privileged -v /root/redis/sentinel1.conf:/data/sentinel.conf -d redis
docker run -it --name redis-sentinel2 --privileged -v /root/redis/sentinel2.conf:/data/sentinel.conf -d redis
docker run -it --name redis-sentinel3 --privileged -v /root/redis/sentinel3.conf:/data/sentinel.conf -d redis
接着使用 /data/sentinel.conf
配置啓動 redis-sentinel,sentinel其實是一個運行在特殊模式下的 Redis實例。
docker exec -it redis-sentinel1 redis-sentinel /data/sentinel.conf
docker exec -it redis-sentinel2 redis-sentinel /data/sentinel.conf
docker exec -it redis-sentinel3 redis-sentinel /data/sentinel.conf
此時任意一臺sentinel節點可以看到的信息:
docker exec -it redis-sentinel3 redis-cli -p 26379
127.0.0.1:26379> info Sentinel
# Sentinel
sentinel_masters:1
master0:name=mymaster,status=ok,address=172.17.0.4:6379,slaves=2,sentinels=3
可以看到:master節點是 172.17.0.4,有2個slave、3個sentinel節點。
自動故障切換測試
停止 master節點,再看看sentinel信息。
docker stop redis-master
很快sentinel會重新選舉一個master,新的節點是:172.17.0.6,不再是172.17.0.4
master0:name=mymaster,status=ok,address=172.17.0.6:6379,slaves=2,sentinels=3
此時再啓動 redis-master,查看其狀態,切換成了slave節點。
docker exec -it redis-master redis-cli -p 6379
127.0.0.1:6379> info Replication
# Replication
role:slave
master_host:172.17.0.6
master_port:6379
master_link_status:up
Spring Boot 使用演示
以一個Spring Boot 2.0.6.RELEASE 程序演示配置及使用,先引入 redis 操作組件依賴(也可以使用Redisson):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置 sentinel 節點:
這裏使用的是容器的IP:Port,需要將本機網絡和容器網絡打通,可參考 Mac 如何訪問容器網絡.
spring:
redis:
sentinel:
master: mymaster
nodes: 172.17.0.2:26379, 172.17.0.3:26379, 172.17.0.7:26379
提供一個簡單的讀寫接口:
@RestController
public class DemoController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@GetMapping("sentinel")
public String sentinel() {
stringRedisTemplate.opsForValue().set("hello", "sentinel");
return stringRedisTemplate.opsForValue().get("hello");
}
}
訪問 http://localhost:8080/sentinel,此時去redis任意節點查看,都能看到 hello:sentinel。
以容器來演示非常方便,實際使用時,使用內部域名將IP全部換掉即可。
歡迎關注公衆號 [陳一樂],一起學習,一起成長