前言
??之前介紹了用docker來(lái)搭建redis主從環(huán)境,但這只是對(duì)數(shù)據(jù)添加了從庫(kù)備份(主從復(fù)制),當(dāng)主庫(kù)down掉的時(shí)候,從庫(kù)是不會(huì)自動(dòng)升級(jí)為主庫(kù)的,也就是說(shuō),該redis主從集群并非是高可用的。
??目前來(lái)說(shuō),高可用(主從復(fù)制、主從切換)redis集群有兩種方案,一種是redis-sentinel,只有一個(gè)master,各實(shí)例數(shù)據(jù)保持一致;一種是redis-cluster,也叫分布式redis集群,可以有多個(gè)master,數(shù)據(jù)分片分布在這些master上。
??本文介紹基于docker和redis-sentinel的高可用redis集群搭建,大多數(shù)情況下,redis-sentinel也需要做高可用,這里先對(duì)redis搭建一主二從環(huán)境,另外需要3個(gè)redis-sentinel監(jiān)控redis master。
??很顯然,只使用單個(gè)redis-sentinel進(jìn)程來(lái)監(jiān)控redis集群是不可靠的,由于redis-sentinel本身也有single-point-of-failure-problem(單點(diǎn)問(wèn)題),當(dāng)出現(xiàn)問(wèn)題時(shí)整個(gè)redis集群系統(tǒng)將無(wú)法按照預(yù)期的方式切換主從。官方推薦:一個(gè)健康的集群部署,至少需要3個(gè)Sentinel實(shí)例。另外,redis-sentinel只需要配置監(jiān)控redis master,而集群之間可以通過(guò)master相互通信。
redis-sentinel
??redis-sentinel作為獨(dú)立的服務(wù),用于管理多個(gè)redis實(shí)例,該系統(tǒng)主要執(zhí)行以下三個(gè)任務(wù):
- 監(jiān)控 (Monitor): 檢查redis主、從實(shí)例是否正常運(yùn)作
- 通知 (Notification): 監(jiān)控的redis服務(wù)出現(xiàn)問(wèn)題時(shí),可通過(guò)API發(fā)送通知告警
- 自動(dòng)故障遷移 (Automatic Failover): 當(dāng)檢測(cè)到redis主庫(kù)不能正常工作時(shí),redis-sentinel會(huì)開(kāi)始做自動(dòng)故障判斷、遷移等操作,先是移除失效redis主服務(wù),然后將其中一個(gè)從服務(wù)器升級(jí)為新的主服務(wù)器,并讓失效主服務(wù)器的其他從服務(wù)器改為復(fù)制新的主服務(wù)器。當(dāng)客戶端試圖連接失效的主服務(wù)器時(shí),集群也會(huì)向客戶端返回最新主服務(wù)器的地址,使得集群可以使用新的主服務(wù)器來(lái)代替失效服務(wù)器
環(huán)境說(shuō)明
- Docker
- Ubuntu/CentOS
- Redis v4.0.10
sentinel.conf
??sentinel.conf
是啟動(dòng)redis-sentinel的核心配置文件,可以從官網(wǎng)下載:
wget http://download.redis.io/redis-stable/sentinel.conf
一主二從
??先搭建好Redis一主二從環(huán)境,這里僅給出操作過(guò)程,可以參考之前寫的《Docker + Redis (4.0.10) 主從環(huán)境搭建》,在master上使用info Replication
查看集群狀態(tài)(注意,為了讓redis-sentinel可以發(fā)現(xiàn)slave,這里要確保redis服務(wù)端口和容器映射端口一致):
# 主庫(kù)
docker run -it --name redis-master -d -p 6300:6300 redis redis-server --requirepass redispassword --port 6300
docker exec -it redis-master bash
redis-cli -a redispassword -p 6300
config set masterauth redispassword
# 從庫(kù)1
docker run -it --name redis-slave -d -p 6301:6301 redis redis-server --requirepass redispassword --port 6301
docker exec -it redis-slave bash
redis-cli -a redispassword -p 6301
slaveof <master-ip> <master-port>
config set masterauth redispassword
# 從庫(kù)2
docker run -it --name redis-slave2 -d -p 6302:6302 redis redis-server --requirepass redispassword --port 6302
docker exec -it redis-slave2 bash
redis-cli -a redispassword -p 6302
slaveof <master-ip> <master-port>
config set masterauth redispassword
配置
??根據(jù)上面下載好的sentinel.conf
,找到并修改如下配置:
# mymaster:自定義集群名,如果需要監(jiān)控多個(gè)redis集群,只需要配置多次并定義不同的<master-name> <master-redis-ip>:主庫(kù)ip <master-redis-port>:主庫(kù)port <quorum>:最小投票數(shù),由于有三臺(tái)redis-sentinel實(shí)例,所以可以設(shè)置成2
sentinel monitor mymaster <master-redis-ip> <master-redis-port> <quorum>
# 注:redis主從庫(kù)搭建的時(shí)候,要么都不配置密碼(這樣下面這句也不需要配置),不然都需要設(shè)置成一樣的密碼
sentinel auth-pass mymaster redispassword
# 添加后臺(tái)運(yùn)行
daemonize yes
??將上面的sentinel.conf
復(fù)制三份,分別為sentinel1.conf
,sentinel2.conf
和sentinel3.conf
,再次編輯修改port
為26000
,26001
和26002
。
啟動(dòng)
??redis-sentinel啟動(dòng)有以下兩種方式:
redis-sentinel /path/to/sentinel.conf
redis-server /path/to/sentinel.conf --sentinel
??大多數(shù)版本的redis都支持以上兩種方式啟動(dòng)。實(shí)戰(zhàn)中,為了讓redis-sentinel作為獨(dú)立的服務(wù)運(yùn)行,這里用docker搭建環(huán)境:
# redis-sentinel實(shí)例1
docker run -it --name redis-sentinel1 -v /root/redis/sentinel1.conf:/usr/local/etc/redis/sentinel.conf -d redis /bin/bash
# redis-sentinel實(shí)例2
docker run -it --name redis-sentinel2 -v /root/redis/sentinel2.conf:/usr/local/etc/redis/sentinel.conf -d redis /bin/bash
# redis-sentinel實(shí)例3
docker run -it --name redis-sentinel3 -v /root/redis/sentinel3.conf:/usr/local/etc/redis/sentinel.conf -d redis /bin/bash
??分別進(jìn)入以上三個(gè)容器啟動(dòng)redis-sentinel:
docker exec -it redis-sentinel(x) bash
# 或redis-server /usr/local/etc/redis/sentinel.conf --sentinel
redis-sentinel /usr/local/etc/redis/sentinel.conf
??連接并使用redis-sentinel API查看監(jiān)控狀況:
redis-cli -p 26000 (26001 | 26002)
sentinel master mymaster 或 sentinel slaves mymaster
測(cè)試
??進(jìn)入redis-master容器,休眠60秒redis服務(wù):
docker exec -it redis-master bash
redis-cli -a redispassword -p 6300 DEBUG sleep 60
??進(jìn)入redis-slave或redis-slave2容器,查看info Replication
,可以看到master已經(jīng)完成了切換。
??60秒后原redis主庫(kù)恢復(fù)服務(wù),但降級(jí)后當(dāng)前redis服務(wù)已無(wú)法恢復(fù)原主庫(kù)身份。
參考
Docker化高可用redis集群
Redis Sentinel Documentation
Redis Sentinel 機(jī)制與用法(4.0.0版本)
Redis practise(二)使用Docker部署Redis高可用,分布式集群