redis應用之使用sentinel實現主從複製高可用

1、redis的高可用管理工具sentinel介紹html

sentinel是一個管理redis實例的工具,它能夠實現對redis的監控、通知、自動故障轉移。sentinel不斷的檢測redis實例是否能夠正常工做,經過API向其餘程序報告redis的狀態,python

若是redis master不能工做,則會自動啓動故障轉移進程,將其中的一個slave提高(經過選舉)爲master,其餘的slave從新設置新的master服務器。而故障的master再次啓動後linux

會被sentinel自動降級爲slave服務器加入到集羣中。git

redis主從的特色:github

一、redis使用異步複製,從服務器會以每秒一次的頻率向主服務器報告複製流的處理進度redis

二、一個主服務器能夠有多個從服務器,從服務器也能夠有本身的從服務器(級聯複製)npm

三、複製功能不會阻塞主服務器,即便一個或多個從服務器正在進行初次同步,主服務器也能夠繼續處理命令請求vim

四、複製功能能夠用於數據冗餘,也能夠經過讓多個從服務器處理只讀命令請求來提高擴展性bash

五、Redis從節點默認爲只讀,無須手動配置服務器

redis的主從集羣能夠實現分擔壓力的效果,可是沒法作到高可用,若是master宕掉,服務就不可用了,因此使用redis的sentinel能夠實現HA的功能:

sentinel做用以下:

一、監控:sentinel會不斷的檢查你的主服務器和從服務器是否運行正常

二、當被監控的某個redis服務器出現問題時,sentinel能夠經過API向管理員或者其餘應用程序發送通知

三、自動故障轉移:當一個主服務器不能正常工做時,sentinel會開始一次自動故障轉移操做,他會將其中一個從服務器升級爲新的主服務器,並將其餘從服務器改成複製新的主服務器;當客戶端試圖鏈接失效的主服務器時,集羣也會向客戶端返回新主服務器的地址,使得集羣可使用新主服務器代替失效服務器。

redis sentinel在監控redis實例時有兩種redis宕機狀態S_DOWN和O_DOWN:

S_DOWN:當sentinel在指定的超時時間內沒有收到一個正確的ping回覆值,則認爲是S_DOWN

O_DOWN:O_DOWN的條件是有足夠多的sentinel認爲該redis實例是S_DOWN。

注意:O_DOWN只能是發生在主服務器,sentinel和其餘從服務器不會發生O_DOWN

2、開始安裝配置主從高可用

一、環境架構:

Centos 6.6 x86_64 redis 3.0.7
master 10.0.18.145 redis port 6379 sentinel port 26379
slave1 10.0.18.146 redis port 6379 sentinel port 26479
slave2 10.0.18.147 redis port 6379 sentinel port 26579
注:redis編譯安裝配置以及主從配置這裏就不在贅述了,請參考以前的redis安裝配置日誌:
http://linuxg.blog.51cto.com/4410110/1862042

架構說明:

a、若是主節點修復後再上線,就會變成從節點。

b、客戶端程序鏈接時,應該鏈接sentinel節點

二、在三臺redis上配置sentinel

先介紹一下sentinel.conf配置文件中經常使用的參數,以下:

port 26379          #sentinel的端口
dir /tmp          #工做目錄
sentinel monitor mymaster 127.0.0.1 6379 2 
#mymaster是自定義的名稱,ip地址是master的ip,6379爲master的redis-server端口
#2是quorum,表示sentinel確認一個Master爲O_DOWN狀態至少須要多少個哨兵贊成(此值要小於等於集羣中slave的個數)
英文翻譯過來是:告訴Sentinel監視這個master,而且只有在至少<quorum> sentinels贊成的狀況下才考慮它是O_DOWN(客觀宕掉)狀態。
sentinel down-after-milliseconds mymaster 30000  #mymaster多久不響應認爲SDOWN,單位是毫秒
sentinel parallel-syncs mymaster 1         #指定最大同時同步新maser配置的slave數量,官方提示用較低的數字,通常爲1
數字越小,故障轉移過程完成所需的時間就越多,若是所有從服務器一塊兒對新的主服務器進行同步,那麼就可能會形成全部從服務器在短期內所有不可用的狀況出現。
sentinel failover-timeout mymaster 180000     #2次failover切換時間,若是第一次沒有failover成功,過多長時間再次failover
注意:不管你設置要多少個Sentinel贊成才能判斷一個服務器失效,一個Sentinel都須要得到系統中多數(majority)Sentinel的支持,才能發起一次自動故障遷移,
並預留一個給定的配置紀元(configuration Epoch,一個配置紀元就是一個新主服務器配置的版本號)。換句話說,在只有少數(minority)Sentinel 進程正常運做的狀況下,
Sentinel 是不能執行自動故障遷移的!

sentinel配置文件以下:

18.145上:
#cat /usr/local/redis/conf/sentinel.conf 
port 26379         
sentinel monitor mymaster 10.0.18.145 6379 1
sentinel auth-pass mymaster abcd123    
sentinel down-after-milliseconds mymaster 60000      #1分鐘
sentinel failover-timeout mymaster 180000            #3分鐘
sentinel parallel-syncs mymaster 1
logfile "/usr/local/redis/log/sentinel_master.log"   #日誌位置
注意:18.146和18.147上的sentinel配置和18.145同樣,只有端口和log不同以下:
slave1 18.146
#cat sentinel.conf
port 26479
logfile "/usr/local/redis/log/sentinel_slave1.log" 
slave2 18.147
#cat sentinel.conf
prot 26579
logfile "/usr/local/redis/log/sentinel_slave2.log"

在master和2臺slave服務器上啓動redis-server和sentinel,確保能夠正常啓動!

#nohup /usr/local/redis/bin/redis-sentinel /usr/local/redis/conf/sentinel.conf &    #我使用此方法
或者nohup /usr/local/redis/bin/redis-server /usr/local/redis/conf/sentinel.conf --sentinel &
查看sentinel進程
#ps aux | grep redis
root     10370  0.1  0.1 137452  2152 ?        Ssl  11:02   0:27 /usr/local/redis/bin/redis-server 10.0.18.145:6379                
root     10474  0.6  0.1 137456  2084 ?        Ssl  15:08   0:00 /usr/local/redis/bin/redis-sentinel *:26379 [sentinel]  
請確保三臺redis的redis-server和sentinel進程均可以正常啓動!

注:Sentinel經過監聽Master,知道了Master的存在,那麼Sentinel能夠讀取Master關於Slave的信息,而後交由Sentinel進行管理!

三、查看sentinel日誌

查看master上的sentinel日誌:

#tail -f sentinel_master.log
………………
13087:X 14 Oct 15:41:21.313 # Sentinel runid is e8b54004648ea00257cfee7150713e86537e3e69
13087:X 14 Oct 15:41:21.313 # +monitor master mymaster 10.0.18.145 6379 quorum 2
13087:X 14 Oct 15:41:21.314 * +slave slave 10.0.18.146:6379 10.0.18.146 6379 @ mymaster 10.0.18.145 6379
13087:X 14 Oct 15:41:21.317 * +slave slave 10.0.18.147:6379 10.0.18.147 6379 @ mymaster 10.0.18.145 6379
13087:X 14 Oct 15:41:36.241 * +sentinel sentinel 10.0.18.146:26479 10.0.18.146 26479 @ mymaster 10.0.18.145 6379
13087:X 14 Oct 15:41:47.947 * +sentinel sentinel 10.0.18.147:26579 10.0.18.147 26579 @ mymaster 10.0.18.145 6379

查看slave1上的sentinel日誌:

#tail -f sentinel_slave1.log
………………
22427:X 14 Oct 15:41:34.145 # Sentinel runid is d0339d3013e855489ff368f6f28a865417ef9818
22427:X 14 Oct 15:41:34.146 # +monitor master mymaster 10.0.18.145 6379 quorum 2
22427:X 14 Oct 15:41:35.147 * +slave slave 10.0.18.146:6379 10.0.18.146 6379 @ mymaster 10.0.18.145 6379
22427:X 14 Oct 15:41:35.158 * +slave slave 10.0.18.147:6379 10.0.18.147 6379 @ mymaster 10.0.18.145 6379
22427:X 14 Oct 15:41:35.574 * +sentinel sentinel 10.0.18.145:26379 10.0.18.145 26379 @ mymaster 10.0.18.145 6379
22427:X 14 Oct 15:41:47.947 * +sentinel sentinel 10.0.18.147:26579 10.0.18.147 26579 @ mymaster 10.0.18.145 6379

查看slave2上的sentinel日誌:

#tail -f sentinel_slave2.log
……………
24207:X 14 Oct 15:41:45.920 # Sentinel runid is 4b63b7796970f93d12e41c648f3a2668864ca5db
24207:X 14 Oct 15:41:45.920 # +monitor master mymaster 10.0.18.145 6379 quorum 2
24207:X 14 Oct 15:41:45.922 * +slave slave 10.0.18.146:6379 10.0.18.146 6379 @ mymaster 10.0.18.145 6379
24207:X 14 Oct 15:41:45.925 * +slave slave 10.0.18.147:6379 10.0.18.147 6379 @ mymaster 10.0.18.145 6379
24207:X 14 Oct 15:41:46.695 * +sentinel sentinel 10.0.18.146:26479 10.0.18.146 26479 @ mymaster 10.0.18.145 6379
24207:X 14 Oct 15:41:47.830 * +sentinel sentinel 10.0.18.145:26379 10.0.18.145 26379 @ mymaster 10.0.18.145 6379

經過以上日誌信息能夠看出,redis主從複製已經OK,sentinel也已經啓動OK!

四、查看主從複製信息和sentinel信息

在master上確認sentinel的信息

#./redis-cli -p 26379   
127.0.0.1:26379> 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.0.18.145:6379,slaves=2,sentinels=3
能夠看到有2臺slave和3臺sentinel,狀態是ok的
確認master的信息
127.0.0.1:26379> sentinel masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "10.0.18.145"
    5) "port"
    6) "6379"
    7) "runid"
    8) "5673ebe1bfd192d44f5c76df952528a38be28b43"  #master的惟一標識id  
    9) "flags"
   10) "master"
   11) "pending-commands"
   12) "0"
   13) "last-ping-sent"
   14) "0"
   15) "last-ok-ping-reply"
   16) "383"
   17) "last-ping-reply"
   18) "383"
   19) "down-after-milliseconds"
   20) "60000"
   21) "info-refresh"
   22) "9715"
   23) "role-reported"
   24) "master"
   25) "role-reported-time"
   26) "1164126"
   27) "config-epoch"
   28) "0"
   29) "num-slaves"
   30) "2"
   31) "num-other-sentinels"
   32) "2"
   33) "quorum"
   34) "2"
   35) "failover-timeout"
   36) "180000"
   37) "parallel-syncs"
   38) "1"
確認slave的信息,以下:
127.0.0.1:26379> sentinel slaves mymaster
1)  1) "name"
    2) "10.0.18.147:6379"
    3) "ip"
    4) "10.0.18.147"
    5) "port"
    6) "6379"
    7) "runid"
    8) "d021efa3c5cb3c6ae695428ad7c6c371bec210dc"  #slave1的惟一標識id
    9) "flags"
   10) "slave"
   11) "pending-commands"
   12) "0"
   13) "last-ping-sent"
   14) "0"
   15) "last-ok-ping-reply"
   16) "510"
   17) "last-ping-reply"
   18) "510"
   19) "down-after-milliseconds"
   20) "60000"
   21) "info-refresh"
   22) "7173"
   23) "role-reported"
   24) "slave"
   25) "role-reported-time"
   26) "1231725"
   27) "master-link-down-time"
   28) "0"
   29) "master-link-status"
   30) "ok"
   31) "master-host"
   32) "10.0.18.145"
   33) "master-port"
   34) "6379"
   35) "slave-priority"
   36) "100"
   37) "slave-repl-offset"
   38) "244198"
2)  1) "name"
    2) "10.0.18.146:6379"
    3) "ip"
    4) "10.0.18.146"
    5) "port"
    6) "6379"
    7) "runid"
    8) "9608029269c840e8b019bf10ce1b242c56cb231d"  #slave2的惟一標識id
    9) "flags"
   10) "slave"
   11) "pending-commands"
   12) "0"
   13) "last-ping-sent"
   14) "0"
   15) "last-ok-ping-reply"
   16) "503"
   17) "last-ping-reply"
   18) "503"
   19) "down-after-milliseconds"
   20) "60000"
   21) "info-refresh"
   22) "7173"
   23) "role-reported"
   24) "slave"
   25) "role-reported-time"
   26) "1231728"
   27) "master-link-down-time"
   28) "0"
   29) "master-link-status"
   30) "ok"
   31) "master-host"
   32) "10.0.18.145"
   33) "master-port"
   34) "6379"
   35) "slave-priority"
   36) "90"
   37) "slave-repl-offset"
   38) "244198"

五、進行容災測試:

a、模擬redis的HA集羣slave服務器宕機

停掉一臺slave,觀察集羣的狀態,這裏將slave2的redis-server停掉

首先查看三臺sentinel的日誌信息,都會刷新一條,以下:

11339:X 13 Oct 10:55:51.391 # +sdown slave 10.0.18.147:6379 10.0.18.147 6379 @ mymaster 10.0.18.145 6379

能夠看到18.147down掉了!

到master服務器上查看主從複製信息:

10.0.18.145:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.18.146,port=6379,state=online,offset=172908,lag=0   
master_repl_offset:172908
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:172907
能夠看到10.0.18.147已經被master剔除了!

再從新將slave2的redis-server啓動起來,繼續觀察:

三臺sentinel的日誌信息,以下:

11339:X 13 Oct 10:59:59.040 * +reboot slave 10.0.18.147:6379 10.0.18.147 6379 @ mymaster 10.0.18.145 6379
11339:X 13 Oct 10:59:59.097 # -sdown slave 10.0.18.147:6379 10.0.18.147 6379 @ mymaster 10.0.18.145 6379
能夠看出18.147已經從新啓動了!
在master上繼續查看複製信息,以下:
10.0.18.145:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=10.0.18.146,port=6379,state=online,offset=224670,lag=0
slave1:ip=10.0.18.147,port=6379,state=online,offset=224670,lag=0
master_repl_offset:224944
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:224943
能夠看到10.0.18.147已經加入到集羣中了

b、模擬redis的HA集羣master服務器宕機 

說明:停掉master的6379端口,假設master是由於外部問題宕機了(直接kill掉redis-server進程)

觀察三臺redis的sentinel日誌:

#tail -f sentinel_master.log
………………
13087:X 14 Oct 16:13:58.625 # +sdown master mymaster 10.0.18.145 6379 #說明18.145down掉了
13087:X 14 Oct 16:13:58.741 # +new-epoch 1
13087:X 14 Oct 16:13:58.766 # +vote-for-leader 4b63b7796970f93d12e41c648f3a2668864ca5db 1  #投票選舉master,能夠根據前面sentinel日誌知道是18.147
13087:X 14 Oct 16:13:59.713 # +odown master mymaster 10.0.18.145 6379 #quorum 3/2          #投票,有2票肯定18.145宕機
13087:X 14 Oct 16:13:59.713 # Next failover delay: I will not start a failover before Fri Oct 14 16:19:59 2016 #第一次failover失敗,繼續
13087:X 14 Oct 16:13:59.820 # +config-update-from sentinel 10.0.18.147:26579 10.0.18.147 26579 @ mymaster 10.0.18.145 6379 #從18.147同步新配置
13087:X 14 Oct 16:13:59.820 # +switch-master mymaster 10.0.18.145 6379 10.0.18.146 6379   #看來已經選舉出了新master爲18.146
13087:X 14 Oct 16:13:59.820 * +slave slave 10.0.18.147:6379 10.0.18.147 6379 @ mymaster 10.0.18.146 6379  #18.147 從新配置(sentinel修改配置來實現)master指向18.146
13087:X 14 Oct 16:13:59.820 * +slave slave 10.0.18.145:6379 10.0.18.145 6379 @ mymaster 10.0.18.146 6379  #18.145降級爲slave,master指向18.146
13087:X 14 Oct 16:14:59.872 # +sdown slave 10.0.18.145:6379 10.0.18.145 6379 @ mymaster 10.0.18.146 6379  #而且檢測到18.145這臺slave處於down狀態
#tail -f sentinel_slave1.log
………………
22427:X 14 Oct 16:13:58.741 # +new-epoch 1
22427:X 14 Oct 16:13:58.767 # +vote-for-leader 4b63b7796970f93d12e41c648f3a2668864ca5db 1 #投票選舉master,選18.147
22427:X 14 Oct 16:13:58.768 # +sdown master mymaster 10.0.18.145 6379
22427:X 14 Oct 16:13:58.824 # +odown master mymaster 10.0.18.145 6379 #quorum 3/2
22427:X 14 Oct 16:13:58.824 # Next failover delay: I will not start a failover before Fri Oct 14 16:19:59 2016 #第一次failover失敗,繼續
22427:X 14 Oct 16:13:59.820 # +config-update-from sentinel 10.0.18.147:26579 10.0.18.147 26579 @ mymaster 10.0.18.145 6379 #從18.147同步新配置
22427:X 14 Oct 16:13:59.820 # +switch-master mymaster 10.0.18.145 6379 10.0.18.146 6379   #看來已經選舉出了新master爲18.146
22427:X 14 Oct 16:13:59.821 * +slave slave 10.0.18.147:6379 10.0.18.147 6379 @ mymaster 10.0.18.146 6379  
22427:X 14 Oct 16:13:59.821 * +slave slave 10.0.18.145:6379 10.0.18.145 6379 @ mymaster 10.0.18.146 6379
22427:X 14 Oct 16:14:59.825 # +sdown slave 10.0.18.145:6379 10.0.18.145 6379 @ mymaster 10.0.18.146 6379
#tail -f sentinel_slave2.log
………………
24207:X 14 Oct 16:13:58.632 # +sdown master mymaster 10.0.18.145 6379
24207:X 14 Oct 16:13:58.698 # +odown master mymaster 10.0.18.145 6379 #quorum 2/2
24207:X 14 Oct 16:13:58.698 # +new-epoch 1
24207:X 14 Oct 16:13:58.698 # +try-failover master mymaster 10.0.18.145 6379    #嘗試failover到18.145,可是18.145redis-server已經down掉
24207:X 14 Oct 16:13:58.701 # +vote-for-leader 4b63b7796970f93d12e41c648f3a2668864ca5db 1 #投票選舉master
24207:X 14 Oct 16:13:58.767 # 10.0.18.145:26379 voted for 4b63b7796970f93d12e41c648f3a2668864ca5db 1 #145一票選18.147
24207:X 14 Oct 16:13:58.769 # 10.0.18.146:26479 voted for 4b63b7796970f93d12e41c648f3a2668864ca5db 1 #146一票選18.147
24207:X 14 Oct 16:13:58.867 # +elected-leader master mymaster 10.0.18.145 6379  #又嘗試選舉18.145
24207:X 14 Oct 16:13:58.868 # +failover-state-select-slave master mymaster 10.0.18.145 6379 #對mymaster進行故障轉移
24207:X 14 Oct 16:13:58.920 # +selected-slave slave 10.0.18.146:6379 10.0.18.146 6379 @ mymaster 10.0.18.145 6379  #18.146當選爲新的master(由於它的slave_priority比較小)
24207:X 14 Oct 16:13:58.921 * +failover-state-send-slaveof-noone slave 10.0.18.146:6379 10.0.18.146 6379 @ mymaster 10.0.18.145 6379 #Sentinel正在將指定的從服務器(10.146)升級爲主服務器,等待升級功能完成。
24207:X 14 Oct 16:13:58.983 * +failover-state-wait-promotion slave 10.0.18.146:6379 10.0.18.146 6379 @ mymaster 10.0.18.145 6379     #等待升級爲master
24207:X 14 Oct 16:13:59.750 # +promoted-slave slave 10.0.18.146:6379 10.0.18.146 6379 @ mymaster 10.0.18.145 6379                    #18.146升級爲master
24207:X 14 Oct 16:13:59.751 # +failover-state-reconf-slaves master mymaster 10.0.18.145 6379   #當前狀態爲從新加載18.145配置,將其降級爲slave,須要在redis.conf中配置slaveof 
24207:X 14 Oct 16:13:59.819 * +slave-reconf-sent slave 10.0.18.147:6379 10.0.18.147 6379 @ mymaster 10.0.18.145 6379
24207:X 14 Oct 16:14:00.775 * +slave-reconf-inprog slave 10.0.18.147:6379 10.0.18.147 6379 @ mymaster 10.0.18.145 6379
24207:X 14 Oct 16:14:00.775 * +slave-reconf-done slave 10.0.18.147:6379 10.0.18.147 6379 @ mymaster 10.0.18.145 6379
24207:X 14 Oct 16:14:00.833 # +failover-end master mymaster 10.0.18.145 6379     #故障轉移完成
24207:X 14 Oct 16:14:00.833 # +switch-master mymaster 10.0.18.145 6379 10.0.18.146 6379 #master變成了18.146
24207:X 14 Oct 16:14:00.834 * +slave slave 10.0.18.147:6379 10.0.18.147 6379 @ mymaster 10.0.18.146 6379
24207:X 14 Oct 16:14:00.835 * +slave slave 10.0.18.145:6379 10.0.18.145 6379 @ mymaster 10.0.18.146 6379
24207:X 14 Oct 16:15:00.845 # +sdown slave 10.0.18.145:6379 10.0.18.145 6379 @ mymaster 10.0.18.146 6379   #並且18.145爲slave,而且判斷爲down狀態

到18.146查看主從集羣狀態信息:

10.0.18.146:6379> auth abcd123
OK
10.0.18.146:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.0.18.147,port=6379,state=online,offset=1067564,lag=0
master_repl_offset:1067701
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:19126
repl_backlog_histlen:1048576
能夠看出此時的18.146已是master了,而且slave服務器只有18.147!

查看sentinel信息:

#./bin/redis-cli -p 26479
127.0.0.1:26479> 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.0.18.146:6379,slaves=2,sentinels=3
哨兵master信息:
127.0.0.1:26479> sentinel masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "10.0.18.146"
    5) "port"
    6) "6379"
    7) "runid"
    8) "9608029269c840e8b019bf10ce1b242c56cb231d"
    9) "flags"
   10) "master"
   11) "pending-commands"
   12) "0"
   13) "last-ping-sent"
   14) "0"
   15) "last-ok-ping-reply"
   16) "399"
   17) "last-ping-reply"
   18) "399"
   19) "down-after-milliseconds"
   20) "60000"
   21) "info-refresh"
   22) "490"
   23) "role-reported"
   24) "master"
   25) "role-reported-time"
   26) "5521890"
   27) "config-epoch"
   28) "1"
   29) "num-slaves"
   30) "2"
   31) "num-other-sentinels"
   32) "2"
   33) "quorum"
   34) "2"
   35) "failover-timeout"
   36) "180000"
   37) "parallel-syncs"
   38) "1"

假如此時10.0.18.145這臺服務器的redis-server恢復了,也會被加入slave隊列中,以下:

先查看18.145上的sentinel日誌
#tail -f sentinel_master.log 
…………
13087:X 14 Oct 17:53:12.701 # -sdown slave 10.0.18.145:6379 10.0.18.145 6379 @ mymaster 10.0.18.146 6379
再查看18.146上的sentinel日誌
#tail -f sentinel_slave1.log 
…………
22427:X 14 Oct 17:53:12.648 # -sdown slave 10.0.18.145:6379 10.0.18.145 6379 @ mymaster 10.0.18.146 6379
22427:X 14 Oct 17:53:22.608 * +convert-to-slave slave 10.0.18.145:6379 10.0.18.145 6379 @ mymaster 10.0.18.146 6379
能夠看到18.145的redis-server進程恢復以後,降級爲slave,被從新加入到集羣中。
再查看18.147上的sentinel日誌
#tail -f sentinel_slave2.log 
…………
24207:X 14 Oct 17:53:12.673 # -sdown slave 10.0.18.145:6379 10.0.18.145 6379 @ mymaster 10.0.18.146 6379

六、查看故障轉移以後redis和sentinel配置文件的變化

a、首先查看三臺redis的redis.conf文件

由於模擬18.145服務器的redis-server宕機然後又從新開啓,因此sentinel機制rewrite了redis.conf文件,以下:

# Generated by CONFIG REWRITE
slaveof 10.0.18.146 6379
rewrite機制在18.145的redis.conf末尾添加了如上2行,表示指向18.146這臺新的master

查看18.146的redis.conf文件,你會發現原來的參數slaveof 10.0.18.145 6379 已經消失了!

查看18.147的redis.conf文件,以下:

slaveof 10.0.18.146 6379  
由原來的指向10.0.18.145變成了指向新的master10.0.18.146

b、查看三臺redis的sentinel.conf文件

10.145上的sentinel.conf文件:
#cat sentinel.conf
port 26379
sentinel monitor mymaster 10.0.18.146 6379 2     #已經由原來的18.145變成了18.146
sentinel down-after-milliseconds mymaster 60000
sentinel auth-pass mymaster abcd123
sentinel config-epoch mymaster 1           
sentinel leader-epoch mymaster 1
logfile "/usr/local/redis/log/sentinel_master.log"
# Generated by CONFIG REWRITE
dir "/usr/local/redis"
sentinel known-slave mymaster 10.0.18.147 6379
sentinel known-slave mymaster 10.0.18.145 6379
sentinel known-sentinel mymaster 10.0.18.147 26579 4b63b7796970f93d12e41c648f3a2668864ca5db   #後邊的字符串是sentinel啓動時候爲每一臺redis生成的惟一標識
sentinel known-sentinel mymaster 10.0.18.146 26479 d0339d3013e855489ff368f6f28a865417ef9818
sentinel current-epoch 1
10.146上的sentinel.conf
#cat sentinel.conf
port 26479
sentinel monitor mymaster 10.0.18.146 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel auth-pass mymaster abcd123
sentinel config-epoch mymaster 1
sentinel leader-epoch mymaster 1
logfile "/usr/local/redis/log/sentinel_slave1.log"
# Generated by CONFIG REWRITE
dir "/usr/local/redis/conf"
sentinel known-slave mymaster 10.0.18.147 6379
sentinel known-slave mymaster 10.0.18.145 6379
sentinel known-sentinel mymaster 10.0.18.147 26579 4b63b7796970f93d12e41c648f3a2668864ca5db
sentinel known-sentinel mymaster 10.0.18.145 26379 e8b54004648ea00257cfee7150713e86537e3e69
sentinel current-epoch 1
10.147上的sentinel.conf
#cat sentinel.conf
port 26579
sentinel monitor mymaster 10.0.18.146 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel auth-pass mymaster abcd123
sentinel config-epoch mymaster 1
sentinel leader-epoch mymaster 1
logfile "/usr/local/redis/log/sentinel_slave2.log"
# Generated by CONFIG REWRITE
dir "/usr/local/redis"
sentinel known-slave mymaster 10.0.18.147 6379
sentinel known-slave mymaster 10.0.18.145 6379
sentinel known-sentinel mymaster 10.0.18.146 26479 d0339d3013e855489ff368f6f28a865417ef9818
sentinel known-sentinel mymaster 10.0.18.145 26379 e8b54004648ea00257cfee7150713e86537e3e69
sentinel current-epoch 1

七、sentinel日誌中的一些參數說明

+reset-master :主服務器已被重置。
+slave :一個新的從服務器已經被 Sentinel 識別並關聯。
+failover-state-reconf-slaves :故障轉移狀態切換到了 reconf-slaves 狀態。
+failover-detected :另外一個 Sentinel 開始了一次故障轉移操做,或者一個從服務器轉換成了主服務器。
+slave-reconf-sent :領頭(leader)的 Sentinel 向實例發送了 [SLAVEOF](/commands/slaveof.html) 命令,爲實例設置新的主服務器。
+slave-reconf-inprog :實例正在將本身設置爲指定主服務器的從服務器,但相應的同步過程仍未完成。
+slave-reconf-done :從服務器已經成功完成對新主服務器的同步。
-dup-sentinel :對給定主服務器進行監視的一個或多個 Sentinel 已經由於重複出現而被移除 —— 當 Sentinel 實例重啓的時候,就會出現這種狀況。
+sentinel :一個監視給定主服務器的新 Sentinel 已經被識別並添加。
+sdown :給定的實例如今處於主觀下線狀態。
-sdown :給定的實例已經再也不處於主觀下線狀態。
+odown :給定的實例如今處於客觀下線狀態。
-odown :給定的實例已經再也不處於客觀下線狀態。
+new-epoch :當前的紀元(epoch)已經被更新。
+try-failover :一個新的故障遷移操做正在執行中,等待被大多數 Sentinel 選中(waiting to be elected by the majority)。
+elected-leader :贏得指定紀元的選舉,能夠進行故障遷移操做了。
+failover-state-select-slave :故障轉移操做如今處於 select-slave 狀態 —— Sentinel 正在尋找能夠升級爲主服務器的從服務器。
no-good-slave :Sentinel 操做未能找到適合進行升級的從服務器。Sentinel 會在一段時間以後再次嘗試尋找合適的從服務器來進行升級,又或者直接放棄執行故障轉移操做。
selected-slave :Sentinel 順利找到適合進行升級的從服務器。
failover-state-send-slaveof-noone :Sentinel 正在將指定的從服務器升級爲主服務器,等待升級功能完成。
failover-end-for-timeout :故障轉移由於超時而停止,不過最終全部從服務器都會開始複製新的主服務器(slaves will eventually be configured to replicate with the new master anyway)。
failover-end :故障轉移操做順利完成。全部從服務器都開始複製新的主服務器了。
+switch-master :配置變動,主服務器的 IP 和地址已經改變。 這是絕大多數外部用戶都關心的信息。
+tilt :進入 tilt 模式。
-tilt :退出 tilt 模式。

注:在http://linuxg.blog.51cto.com/4410110/1862042這篇博客中我是從redis源碼中複製的redis.conf文件而不是手動建立的,是由於我配置sentinel高可用(暨redis應用之使用sentinel實現主從複製高可用)的過程當中遇到一個坑,使用手動自建立的redis.conf,當停掉master的redis-server進程的時候,sentinel沒法經過選舉實現failover,日誌中一直是failover 超時,百思不得其解,也在google尋找解決方案無果,後來改成複製源碼中的redis.conf,而後failover就OK了!

八、Sentinel的客戶端

若是要作到應用程序(客戶端)對Redis的failover透明Transparent),客戶端須要監控sentinel的頻道信息,並自動鏈接新的主節點。官方提供了一個專門的topic來說解這個問題:Guidelines for Redis clients with support for Redis Sentinel而一些經常使用的開發語言也已經有了整合sentinel的redis driver,以下:

Node.JS redis-sentinel-client — Transparent Redis Sentinel client

Python redis 2.10.3

Java Jedis

以Python爲例,首先安裝redis-py

#pip install redis

一個簡單的測試代碼以下,首先得到一個Sentinel對象,而後

#vim sentinel.py
from redis.sentinel import Sentinel
sentinel = Sentinel([('localhost', 26379)], socket_timeout=0.1)
master = sentinel.master_for('myredis', socket_timeout=0.1)
master.set('foo', 'bar')
slave = sentinel.slave_for('myredis', socket_timeout=0.1)
slave.get('foo')

執行後成功獲得bar這個值

python sentinel.py 
bar

上面的master和slave都是標準的創建好鏈接的StrictRedis實例,slave則是sentinel查詢到的第一個可用的slave。若是正在鏈接的master不可用時,客戶端會先拋出redis.exceptions.ConnectionError異常(此時還沒開始failover),而後拋出redis.sentinel.MasterNotFoundError異常(failover進行中),在sentinel正常failover以後,實例正常。因此要開發一個sentinel的高可用客戶端,能夠參考上面那篇官方的指導。

參考連接:

http://debugo.com/redis-sentinel/

http://www.fblinux.com/?p=157

不足之處,請多多指出!

相關文章
相關標籤/搜索