1. 程式人生 > >Redis-sentinel哨兵模式集群方案配置

Redis-sentinel哨兵模式集群方案配置

系統/運維 Linux

最近研究了redis的集群方案,第一個方案是創建 redis cluster,第二種方案就是用哨兵模式來進行主從替換以及故障恢復。


一、sentinel介紹


Redis Sentinel

Sentinel(哨兵)是用於監控redis集群中Master狀態的工具,其已經被集成在redis2.4+的版本中。

Sentinel作用:

1):Master狀態檢測 
2):如果Master異常,則會進行Master-Slave切換,將其中一個Slave作為Master,將之前的Master作為Slave 
3):Master-Slave切換後,master_redis.conf、slave_redis.conf和sentinel.conf的內容都會發生改變,即master_redis.conf中會多一行slaveof的配置,sentinel.conf的監控目標會隨之調換

Sentinel工作方式:

1):每個Sentinel以每秒鐘一次的頻率向它所知的Master,Slave以及其他 Sentinel 實例發送一個 PING 命令 
2):如果一個實例(instance)距離最後一次有效回復 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個實例會被 Sentinel 標記為主觀下線。 
3):如果一個Master被標記為主觀下線,則正在監視這個Master的所有 Sentinel 要以每秒一次的頻率確認Master的確進入了主觀下線狀態。 
4):當有足夠數量的 Sentinel(大於等於配置文件指定的值)在指定的時間範圍內確認Master的確進入了主觀下線狀態, 則Master會被標記為客觀下線 
5):在一般情況下, 每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有Master,Slave發送 INFO 命令 
6):當Master被 Sentinel 標記為客觀下線時,Sentinel 向下線的 Master 的所有 Slave 發送 INFO 命令的頻率會從 10 秒一次改為每秒一次 
7):若沒有足夠數量的 Sentinel 同意 Master 已經下線, Master 的客觀下線狀態就會被移除。 
若 Master 重新向 Sentinel 的 PING 命令返回有效回復, Master 的主觀下線狀態就會被移除

主觀下線和客觀下線:

主觀下線:Subjectively Down,簡稱 SDOWN,指的是當前 Sentinel 實例對某個redis服務器做出的下線判斷。 
客觀下線:Objectively Down, 簡稱 ODOWN,指的是多個 Sentinel 實例在對Master Server做出 SDOWN 判斷,並且通過 SENTINEL is-master-down-by-addr 命令互相交流之後,得出的Master Server下線判斷,然後開啟failover.

通俗來講就是:

redis的sentinel系統用來管理多個redis服務器,可以實現一個功能上實現HA的集群。該系統主要執行四個任務:

①監控( Monitoring ): Redis Sentinel實時監控主服務器和從服務器運行狀態。 
②提醒(notification): 當被監控的某個 Redis 服務器出現問題時, Redis Sentinel 可以向系統管理員發送通知, 也可以通過 API 向其他程序發送通知。 
③自動故障轉移:如果一個master不正常運行了,哨兵可以啟動一個故障轉移進程,將一個slave升級成為master,其他的slave被重新配置使用新的master,並且應用程序使用Redis服務端通知的新地址。
④配置提供者:哨兵作為Redis客戶端發現的權威來源:客戶端連接到哨兵請求當前可靠的master的地址。如果發生故障,哨兵將報告新地址。


二、搭建redis-sentinel 集群環境

0、安裝redis

操作系統:CentOS6.5 
wget http://download.redis.io/releases/redis-3.2.1.tar.gz
tar -xzf redis-3.2.1.tar.gz 
cd redis-3.2.1 
yum -y install gcc
make [MALLOC=libc]
make install 

或者
make PREFIX=/usr/local/redis install  #默認安裝位置為/usr/local/bin
echo "export PATH=/usr/local/redis/bin:$PATH" >> /etc/profile.d/redis.sh
source /etc/profile.d/redis.sh

1、在/usr/local/ 下新建一個目錄redis-sentinel,然後在此目錄下新建7501/ 7502/ 7503/ 7504/ 7505/ 7506/ 7507/七個目錄。

mkdir /usr/local/redis-sentinel 
mkdir /usr/local/redis-sentinel/{7501,7502,7503,7504,7505,7506,7507}

2、將redis安裝目錄下的reids.conf,拷貝到前4個目錄下,分別命名為:redis-7501.conf redis-7502.conf redis-7503.conf redis-7504.conf

cp /root/redis-3.2.1/redis.conf /usr/local/redis-sentinel/7501/redis-7501.conf
cp /root/redis-3.2.1/redis.conf /usr/local/redis-sentinel/7502/redis-7502.conf
cp /root/redis-3.2.1/redis.conf /usr/local/redis-sentinel/7503/redis-7503.conf
cp /root/redis-3.2.1/redis.conf /usr/local/redis-sentinel/7504/redis-7504.conf

修改配置文件內容(以redis-7501.conf為例):

daemonize yes
pidfile /var/run/redis_7501.pid
port 7501
bind 10.10.172.191  #可選,默認就處理所有請求。
logfile "./redis-7501.log"
dir "/usr/local/redis-sentinel/7501"
redis配置密碼的話,需要以下配置
masterauth "123456"
requirepass "123456"
appendonly yes

3、 將redis安裝目錄下的sentinel.conf拷貝到7505/ 7506/和7507/目錄下分別命名: sentinel-7505.conf sentinel-7506.conf sentinel-7507.conf

cp /root/redis-3.2.1/sentinel.conf /usr/local/redis-sentinel/7505/sentinel-7505.conf
cp /root/redis-3.2.1/sentinel.conf /usr/local/redis-sentinel/7506/sentinel-7506.conf
cp /root/redis-3.2.1/sentinel.conf /usr/local/redis-sentinel/7507/sentinel-7507.conf

修改配置文件(以sentinel-7505.conf為例):

daemonize yes 
port 7505
#指定工作目錄
dir "/usr/local/redis-sentinel/7505"
logfile "./sentinel.log" 
sentinel monitor mymaster 10.10.172.191 7501 2
#如果3s內mymaster無響應,則認為mymaster宕機了,默認30s  
sentinel down-after-milliseconds mymaster 3000   @30000  
sentinel parallel-syncs mymaster 1
#如果18秒後,master仍沒活過來,則啟動failover,,默認30s  
sentinel failover-timeout mymaster 10000 
#redis主節點密碼  
sentinel auth-pass mymaster 123456  
註:我們稍後要啟動四個redis實例,其中端口為7501的redis設為master,其他三個設為slave 。所以mymaster 後跟的是master的ip和端口,最後一個'2'代表我要啟動只要有2個sentinel認為master下線,就認為該master客觀下線,啟動failover並選舉產生新的master。通常最後一個參數不能多於啟動的sentinel實例數。建議至少啟動三臺sentinel實例。

4、啟動redis和sentinel

分別啟動4個redis實例:

redis-server /usr/local/redis-sentinel/7501/redis-7501.conf 
redis-server /usr/local/redis-sentinel/7502/redis-7502.conf  
redis-server /usr/local/redis-sentinel/7503/redis-7503.conf  
redis-server /usr/local/redis-sentinel/7504/redis-7504.conf

然後分別登陸7502 7503 7504三個實例,動態改變主從關系,成為7501的slave:

redis-cli -h 10.10.172.191 -p 7502
10.10.172.191:7502> SLAVEOF 10.10.172.191 7501
#這裏也可以事先直接修改從實例redis文件追加slaveof 10.10.172.191 6379

查看主從狀態:

10.10.172.191:7501> info replication
# Replication
role:master
connected_slaves:3
slave0:ip=10.10.172.191,port=7502,state=online,offset=127,lag=0
slave1:ip=10.10.172.191,port=7503,state=online,offset=127,lag=0
slave2:ip=10.10.172.191,port=7504,state=online,offset=127,lag=1
master_repl_offset:127
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:126

註:從庫末尾會自動添加同步語句slaveof 10.10.172.191 7501。

以後臺啟動模式啟動兩個sentinel(哨兵):

redis-sentinel /usr/local/redis-sentinel/7505/sentinel-7505.conf
redis-sentinel /usr/local/redis-sentinel/7506/sentinel-7506.conf
redis-sentinel /usr/local/redis-sentinel/7507/sentinel-7507.conf

查看redis進程狀態

[root@localhost ~]# ps -ef|grep redis
root      2121     1  0 10:11 ?        00:00:00 redis-server 10.10.172.191:7501                            
root      2125     1  0 10:11 ?        00:00:00 redis-server 10.10.172.191:7502                            
root      2129     1  0 10:11 ?        00:00:00 redis-server 10.10.172.191:7503                            
root      2133     1  0 10:11 ?        00:00:00 redis-server 10.10.172.191:7504                            
root      2156     1  0 10:15 ?        00:00:00 redis-sentinel *:7505 [sentinel]                                
root      2160     1  0 10:15 ?        00:00:00 redis-sentinel *:7506 [sentinel]                                
root      2164     1  0 10:15 ?        00:00:00 redis-sentinel *:7507 [sentinel]                                
root      2169  1858  0 10:16 pts/0    00:00:00 grep redis

5、sentinel一些命令介紹

要使用sentinel的命令,我們需要用redis-cli命令進入到sentinel:
redis-cli -h 10.10.172.191 -p 7505 -a 123456

①INFO 
sentinel的基本狀態信息 
②SENTINEL masters | SENTINEL master mymaster
列出所有被監視的主服務器,以及這些主服務器的當前狀態 
③ SENTINEL slaves mymaster
列出給定主服務器的所有從服務器,以及這些從服務器的當前狀態 
④SENTINEL get-master-addr-by-name mymaster
返回給定名字的主服務器的 IP 地址和端口號 
⑤SENTINEL reset 
重置所有名字和給定模式 pattern 相匹配的主服務器。重置操作清除主服務器目前的所有狀態, 包括正在執行中的故障轉移, 並移除目前已經發現和關聯的, 主服務器的所有從服務器和 Sentinel 。 
⑥SENTINEL failover 
當主服務器失效時, 在不詢問其他 Sentinel 意見的情況下, 強制開始一次自動故障遷移,但是它會給其他sentinel發送一個最新的配置,其他sentinel會根據這個配置進行更新.

6、測試:

(1)登陸到 master:

# redis-cli -h 10.10.172.191 -p 7501 -a 123456
10.10.172.191:7501> info Replication  #列出Master的信息
10.10.172.191:7501> set name "zhangsan"
# redis-cli -h 10.10.172.191 -p 7502
10.10.172.191:7502> get name
"zhangsan"
10.10.172.191:7502> set age 24
(error) READONLY You can't write against a read only slave.

可以看到:我們的主從模式中,slave默認是只讀。


(2)目前7501是master, 我們強制kill掉 7501 的進程以後,查看sentinel打出的日誌信息:

# tail -fn 10 /usr/local/redis-sentinel/7505/sentinel.log  
2156:X 28 Mar 10:25:54.960 # +new-epoch 2
2156:X 28 Mar 10:25:54.962 # +vote-for-leader a786b1a5a73cc8251ce888704024a14e417e33af 2
2156:X 28 Mar 10:25:54.992 # +odown master mymaster 10.10.172.191 7501 #quorum 3/2
2156:X 28 Mar 10:25:54.992 # Next failover delay: I will not start a failover before Wed Mar 28 10:26:15 2018
2156:X 28 Mar 10:25:56.037 # +config-update-from sentinel 10.10.172.191:7507 10.10.172.191 7507 @ mymaster 10.10.172.191 7501
2156:X 28 Mar 10:25:56.037 # +switch-master mymaster 10.10.172.191 7501 10.10.172.191 7502
2156:X 28 Mar 10:25:56.037 * +slave slave 10.10.172.191:7504 10.10.172.191 7504 @ mymaster 10.10.172.191 7502
2156:X 28 Mar 10:25:56.037 * +slave slave 10.10.172.191:7503 10.10.172.191 7503 @ mymaster 10.10.172.191 7502
2156:X 28 Mar 10:25:56.037 * +slave slave 10.10.172.191:7501 10.10.172.191 7501 @ mymaster 10.10.172.191 7502
2156:X 28 Mar 10:25:59.085 # +sdown slave 10.10.172.191:7501 10.10.172.191 7501 @ mymaster 10.10.172.191 7502

可以看到,sentinel已經將7502這個redis instance提升為新的master,稍後將7501這個實例啟動,動態作為7501的slave,這樣就手動恢復了redis 集群。同時也在redis-7501.conf文件末尾看到主從同步配置語句“slaveof 10.10.172.191 7502”。

停止並啟動實例7501
kill -9 2121
redis-server /usr/local/redis-sentinel/7501/redis-7501.conf

查看當前redis主從狀態
[root@localhost ~]# redis-cli -h 10.10.172.191 -p 7505
10.10.172.191:7505> INFO Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=10.10.172.191:7502,slaves=3,sentinels=3

連接redis主實例查看主從狀態並創建key
[root@localhost ~]# redis-cli -h 10.10.172.191 -p 7502 -a 123456  
10.10.172.191:7502> info replication
# Replication
role:master
connected_slaves:3
slave0:ip=10.10.172.191,port=7504,state=online,offset=58539,lag=1
slave1:ip=10.10.172.191,port=7503,state=online,offset=58819,lag=0
slave2:ip=10.10.172.191,port=7501,state=online,offset=58679,lag=0
master_repl_offset:58959
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:58958
10.10.172.191:7502> keys *
1) "name"
10.10.172.191:7502> set age 24
OK
10.10.172.191:7502> exit

redis從實例上查看key
[root@localhost ~]# redis-cli -h 10.10.172.191 -p 7501 -a 123456
10.10.172.191:7501> keys *
1) "name"
2) "age"
10.10.172.191:7501> get age
"24"

7、開機自動啟動redis和sentinel:

將以下代碼追加到/etc/rc.local文件末尾 
/usr/local/bin/redis-server /usr/local/redis-sentinel/7501/redis-7501.conf 
/usr/local/bin/redis-server /usr/local/redis-sentinel/7502/redis-7502.conf  
/usr/local/bin/redis-server /usr/local/redis-sentinel/7503/redis-7503.conf  
/usr/local/bin/redis-server /usr/local/redis-sentinel/7504/redis-7504.conf
/usr/local/bin/redis-sentinel /usr/local/redis-sentinel/7505/sentinel-7505.conf
/usr/local/bin/redis-sentinel /usr/local/redis-sentinel/7506/sentinel-7506.conf
/usr/local/bin/redis-sentinel /usr/local/redis-sentinel/7507/sentinel-7507.conf


Redis-sentinel哨兵模式集群方案配置