1. 程式人生 > >Redis 哨兵叢集模式

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指令碼實現;