Redis 哨兵叢集模式
一、Redis sentinel 概述;
概述:Sentinel:哨兵模式,是一個分散式系統,該程序是用於監控redis叢集中Master主伺服器工作的狀態,在Master主伺服器發生故障的時候,可以實現Master和Slave伺服器的切換,保證系統的高可用,其已經被整合在redis 2.6 +的版本中,Redis的哨兵模式到了2.8版本之後就得到了穩定;
二、Redis sentinel的工作機制;
工作程序:
- 監控(Monitoring): 哨兵(sentinel)通過流言協議(gossip protocols)會不斷地檢查你的Master和Slave是否運作正常;
- 提醒(Notification):當被監控的某個Redis節點出現問題時, 哨兵(sentinel)可以通過 API 向管理員或者其他應用程式傳送通知;
- 自動故障遷移(Automatic failover):當一個Master不能正常工作時,哨兵通過投票協議(Agreement Protocols)會開始一次自動故障遷移操作,它會將其他一個Slave升級為新的Master,當客戶端試圖連線失效的Master時,叢集也會向客戶端返回新Master的地址,使得叢集可以使用現在的Master替換失效Master。Master和Slave伺服器切換後,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置檔案的內容都會發生相應的改變,即,Master主伺服器的redis.conf配置檔案中會多一行slaveof的配置,sentinel.conf的監控目標會隨之調換;
圖解:
三、案例:構建Redis sentinel叢集;
案例環境:
系統型別 |
IP地址 |
主機名 |
所需軟體 |
埠 |
Centos7.4 1708 64bit |
192.168.100.101 |
master.linuxfan.cn |
redis-4.0.9.tar.gz |
redis:6379 redis sentinel:26379 |
Centos7.4 1708 64bit |
192.168.100.102 |
slave1.linuxfan.cn |
redis-4.0.9.tar.gz |
redis:6379 |
Centos7.4 1708 64bit |
192.168.100.103 |
slave2.linuxfan.cn |
redis-4.0.9.tar.gz |
redis:6379 |
案例步驟:
- 安裝所有節點的redis服務(所有節點配置相同,在此列舉master節點配置);
- 修改master節點的配置檔案,實現主從複製;
- 修改slave節點的配置檔案,實現主從複製(兩個slave節點配置相同,在此列舉slave1節點配置);
- 驗證主從節點的主從同步;
- 在master節點上配置Redis sentinel;
- 在master節點上啟動Redis sentinel;
- 測試Redis sentinel,關閉master節點後,測試叢集切換;
- 驗證新的master節點與slave節點之間的主從同步;
- 恢復master節點,驗證叢集狀態;
- 擴充套件:如若實現master節點切換後,保證IP地址的統一性,可以選擇使用Keepalived及shell指令碼實現;
- 安裝所有節點的redis服務(所有節點配置相同,在此列舉master節點配置);
[[email protected] ~]# wget http://download.redis.io/releases/redis-4.0.9.tar.gz
[[email protected] ~]# tar zxvf redis-4.0.9.tar.gz
[[email protected] ~]# cd redis-4.0.9
[[email protected] redis-4.0.9]# make
[[email protected] redis-4.0.9]# echo $?
[[email protected] redis-4.0.9]# cd
[[email protected] ~]# mkdir -p /usr/local/redis
[[email protected] ~]# cp /root/redis-4.0.9/src/redis-server /usr/local/redis/
[[email protected] ~]# cp /root/redis-4.0.9/src/redis-cli /usr/local/redis/
[[email protected] ~]# cp /root/redis-4.0.9/redis.conf /usr/local/redis/
[[email protected] ~]# ls /usr/local/redis/
redis-cli redis.conf redis-server
[[email protected] ~]# sed -i '/^bind 127.0.0.1$/s/127.0.0.1/192.168.100.101/g' /usr/local/redis/redis.conf
[[email protected] ~]# sed -i '/protected-mode/s/yes/no/g' /usr/local/redis/redis.conf ##關閉redis的保護模式
[[email protected] ~]# sed -i '/daemonize/s/no/yes/g' /usr/local/redis/redis.conf ##開啟redis的後臺守護程序模式
[[email protected] ~]# sed -i '/requirepass/s/foobared/123123/g' /usr/local/redis/redis.conf ##設定redis的密碼為123123
[[email protected] ~]# sed -i '/requirepass 123123/s/^#//g' /usr/local/redis/redis.conf ##開啟redis的密碼
[[email protected] ~]# ln -s /usr/local/redis/redis-cli /usr/local/bin/redis
[[email protected] ~]# cat <<END >>/etc/init.d/redis
#!/bin/sh
# chkconfig: 2345 80 90
# description: Start and Stop redis
#PATH=/usr/local/bin:/sbin:/usr/bin:/bin
REDISPORT=6379
EXEC=/usr/local/redis/redis-server
REDIS_CLI=/usr/local/redis/redis-cli
PIDFILE=/var/run/redis_6379.pid
CONF="/usr/local/redis/redis.conf"
AUTH="123123"
LISTEN_IP=\$(netstat -utpln |grep redis-server |awk '{print \$4}'|awk -F':' '{print \$1}')
case "\$1" in
start)
if [ -f \$PIDFILE ]
then
echo "\$PIDFILE exists, process is already running or crashed"
else
echo "Starting Redis server..."
\$EXEC \$CONF
fi
if [ "\$?"="0" ]
then
echo "Redis is running..."
fi
;;
stop)
if [ ! -f \$PIDFILE ]
then
echo "\$PIDFILE does not exist, process is not running"
else
PID=\$(cat \$PIDFILE)
echo "Stopping ..."
\$REDIS_CLI -h \$LISTEN_IP -p \$REDISPORT -a \$AUTH SHUTDOWN
while [ -x \${PIDFILE} ]
do
echo "Waiting for Redis to shutdown ..."
sleep 1
done
echo "Redis stopped"
fi
;;
restart|force-reload)
\${0} stop
\${0} start
;;
*)
echo "Usage: /etc/init.d/redis {start|stop|restart|force-reload}" >&2
exit 1
esac
END
[[email protected] ~]# chmod 755 /etc/init.d/redis
[[email protected] ~]# chkconfig --add redis
[[email protected] ~]# /etc/init.d/redis start
Starting Redis server...
4390:C 04 May 02:16:45.232 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
4390:C 04 May 02:16:45.232 # Redis version=4.0.9, bits=64, commit=00000000, modified=0, pid=4390, just started
4390:C 04 May 02:16:45.232 # Configuration loaded
Redis is running...
[[email protected] ~]# netstat -utpln |grep redis
tcp 0 192.168.100.101:6379 0.0.0.0:* LISTEN 4204/redis-server *
[[email protected] ~]# redis -h 192.168.100.101 -a 123123 -p 6379
192.168.100.101:6379> exit
- 修改master節點的配置檔案,實現主從複製;
[[email protected] ~]# sed -i '450s/^\(.\).\{22\}/min-slaves-to-write 2/g' /usr/local/redis/redis.conf
##設定slave節點的數量,如果slave節點數量少於此值,那麼master節點將停止客戶端的一切寫請求
[[email protected] ~]# sed -n '451s/^\(.\).\{22\}/min-slaves-max-lag 10/g' /usr/local/redis/redis.conf
##master與slave之間同步資料的超時時間,若超過此時間,master節點將停止客戶端的一切寫操作
[[email protected] ~]# /etc/init.d/redis restart
Stopping ...
Redis stopped
...
- 修改slave節點的配置檔案,實現主從複製(兩個slave節點配置相同,在此列舉slave1節點配置);
[[email protected] ~]# sed -i '281s/^\(.\).\{32\}/slaveof 192.168.100.101 6379/g' /usr/local/redis/redis.conf
##指定master的ip地址以及埠
[[email protected] ~]# sed -i '288s/^\(.\).\{29\}/masterauth 123123/g' /usr/local/redis/redis.conf
##指定master的連線密碼
[[email protected] ~]# /etc/init.d/redis restart
/var/run/redis_6379.pid does not exist, process is not running
Starting Redis server...
4387:C 18 May 03:24:00.027 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
4387:C 18 May 03:24:00.027 # Redis version=4.0.9, bits=64, commit=00000000, modified=0, pid=4387, just started
4387:C 18 May 03:24:00.027 # Configuration loaded
Redis is running...
- 驗證主從節點的主從同步;
- 在master節點上配置Redis sentinel;
[[email protected] ~]# cp redis-4.0.9/src/redis-sentinel /usr/local/redis/ ## sentinel啟動指令碼
[[email protected] ~]# cp redis-4.0.9/sentinel.conf /usr/local/redis/ ## sentinel配置檔案
[[email protected] ~]# mkdir -p /var/redis/data ##建立日誌檔案存放位置
[[email protected] ~]# vi /usr/local/redis/sentinel.conf ##修改如下
port 26379
dir "/var/redis/data"
sentinel monitor master.linuxfan.cn 192.168.100.101 6379 1 ## 1表示當一臺master出現故障,則進行切換
sentinel down-after-milliseconds master.linuxfan.cn 3000 ##指定master的失效時間,單位毫秒,3秒
sentinel auth-pass master.linuxfan.cn 123123 ##連線master與slave節點的密碼
sentinel config-epoch master.linuxfan.cn 1 ##切換後,最多有多少節點可以與新的master進行同步
sentinel failover-timeout mymaster 180000 ##切換操作完成的時間週期為180秒,逾期認為切換失敗
:wq
- 在master節點上啟動Redis sentinel;
[[email protected] ~]# netstat -utpln |grep redis-sen
tcp 0 0 0.0.0.0:26379 0.0.0.0:* LISTEN 4324/redis-setinel
- 測試Redis sentinel,關閉master節點後,測試叢集切換;
註解:Sentinel日誌語句所表達的意義
+reset-master <instance details> -- 當master被重置時.
+slave <instance details> -- 當檢測到一個slave並新增進slave列表時.
+failover-state-reconf-slaves <instance details> -- Failover狀態變為reconf-slaves狀態時
+failover-detected <instance details> -- 當failover發生時
+slave-reconf-sent <instance details> -- sentinel傳送SLAVEOF命令把它重新配置時
+slave-reconf-inprog <instance details> -- slave被重新配置為另外一個master的slave,但資料複製還未發生時。
+slave-reconf-done <instance details> -- slave被重新配置為另外一個master的slave並且資料複製已經與master同步時。
-dup-sentinel <instance details> -- 刪除指定master上的冗餘sentinel時 (當一個sentinel重新啟動時,可能會發生這個事件).
+sentinel <instance details> -- 當master增加了一個sentinel時。
+sdown <instance details> -- 進入SDOWN狀態時;
-sdown <instance details> -- 離開SDOWN狀態時。
+odown <instance details> -- 進入ODOWN狀態時。
-odown <instance details> -- 離開ODOWN狀態時。
+new-epoch <instance details> -- 當前配置版本被更新時。
+try-failover <instance details> -- 達到failover條件,正等待其他sentinel的選舉。
+elected-leader <instance details> -- 被選舉為去執行failover的時候。
+failover-state-select-slave <instance details> -- 開始要選擇一個slave當選新master時。
no-good-slave <instance details> -- 沒有合適的slave來擔當新master
selected-slave <instance details> -- 找到了一個適合的slave來擔當新master
failover-state-send-slaveof-noone <instance details> -- 當把選擇為新master的slave的身份進行切換的時候。
failover-end-for-timeout <instance details> -- failover由於超時而失敗時。
failover-end <instance details> -- failover成功完成時。
switch-master <master name> <oldip> <oldport> <newip> <newport> -- 當master的地址發生變化時。通常這是客戶端最感興趣的訊息了。
+tilt -- 進入Tilt模式。
-tilt -- 退出Tilt模式。
- 驗證新的master節點與slave節點之間的主從同步;
- 恢復master節點,驗證叢集狀態;
- 擴充套件:如若實現master節點切換後,保證IP地址的統一性,可以選擇使用Keepalived及shell指令碼實現;