哨兵(sentinel),用於對主從結構中的每一臺服務器進行監控,當主節點出現故障後經過投票機制來挑選新的主節點,而且將全部的從節點鏈接到新的主節點上。前面的主從是最基礎的提高Redis服務器穩定性的一種實現方式,但咱們能夠看到master節點仍然是一臺,若主節點宕機,全部從服務器都不會有新的數據進來,如何讓主節點也實現高可用,當主節點宕機的時候自動從從節點中選舉一臺節點提高爲主節點就是哨兵實現的功能。redis
1.監控:監控主從節點運行狀況。
2.通知:當監控節點出現故障,哨兵之間進行通信。
自動故障轉移:當監控到主節點宕機後,斷開與宕機主節點鏈接的全部從節點,而後在從節點中選取一個做爲主節點,將其餘的從節點鏈接到這個最新的主節點。最後通知客戶端最新的服務器地址。緩存
1.每一個Sentinel以每秒鐘一次的頻率向它所知的Master,Slave以及其餘 Sentinel 實例發送一個PING命令。
2.若是一個實例(instance)距離最後一次有效回覆PING命令的時間超過 own-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秒一次改成每秒一次。
若沒有足夠數量的Sentinel贊成Master已經下線,Master的客觀下線狀態就會被移除。 若 Master從新向7.Sentinel 的PING命令返回有效回覆,Master的主觀下線狀態就會被移除。bash
主機名 | ip地址端口 | 角色 |
---|---|---|
sentinel | 10.0.0.88 26380 | 哨兵1 |
sentinel | 10.0.0.88 26381 | 哨兵2 |
sentinel | 10.0.0.88 26382 | 哨兵3 |
# pid文件路徑 pidfile /var/run/redis-sentinel.pid # 日誌文件路徑 logfile "/var/log/sentinel.log" # 定義工做目錄 dir /tmp # 定義Redis主的別名, IP, 端口,這裏的2指的是須要至少2個Sentinel認爲主Redis掛了才最終會採起下一步行爲 # sentinel monitor [集羣名稱] [集羣主節點IP] [斷開] [] sentinel monitor mymaster 127.0.0.1 6379 2 # 若是mymaster 30秒內沒有響應,則認爲其主觀失效 sentinel down-after-milliseconds mymaster 30000 # 若是master從新選出來後,其它slave節點能同時並行重新master同步數據的臺數有多少個,顯然該值越大,全部slave節點完成同步切換的總體速度越快,但若是此時正好有人在訪問這些slave,可能形成讀取失敗,影響面會更廣。最保守的設置爲1,同一時間,只能有一臺幹這件事,這樣其它slave還能繼續服務,可是全部slave所有完成緩存更新同步的進程將變慢。 sentinel parallel-syncs mymaster 1 # 該參數指定一個時間段,在該時間段內沒有實現故障轉移成功,則會再一次發起故障轉移的操做,單位毫秒 sentinel failover-timeout mymaster 180000 # 不容許使用SENTINEL SET設置notification-script和client-reconfig-script。 sentinel deny-scripts-reconfig yes # 主庫帳號密碼 sentinel auth-pass mymaster 123 sentinel auth-user mymaster default # 三個哨兵示例配置 [root@sentinel /usr/local/redis/conf]# egrep -v '^#|^$' sentinel_26380.conf port 26380 daemonize yes pidfile /var/run/redis-sentinel_26380.pid logfile "/usr/local/redis/conf/sentinel_26380.log" dir /tmp sentinel monitor mymaster 172.16.1.81 6379 2 sentinel down-after-milliseconds mymaster 30000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000 sentinel deny-scripts-reconfig yes sentinel auth-pass mymaster 123 sentinel auth-user mymaster default
[root@sentinel /usr/local/redis/conf]# ../bin/redis-sentinel sentinel_26380.conf [root@sentinel /usr/local/redis/conf]# ../bin/redis-sentinel sentinel_26381.conf [root@sentinel /usr/local/redis/conf]# ../bin/redis-sentinel sentinel_26382.conf [root@sentinel /usr/local/redis/conf]# netstat -lntp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:26380 0.0.0.0:* LISTEN 11591/../bin/redis- tcp 0 0 0.0.0.0:26381 0.0.0.0:* LISTEN 11600/../bin/redis- tcp 0 0 0.0.0.0:26383 0.0.0.0:* LISTEN 11608/../bin/redis-
[root@sentinel /usr/local/redis/conf]# ../bin/redis-cli -p 26380 127.0.0.1:26380> sentinel master mymaster 1) "name" 2) "mymaster" 3) "ip" 4) "172.16.1.81" 5) "port" 6) "6379" 7) "runid" 8) "63e1b63288c82c1ff20784626042aeaadd23f2d0" 9) "flags" 10) "master" 11) "link-pending-commands" 12) "0"
# 停掉主庫 [root@redis01 /usr/local/redis/conf]# netstat -lntp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 172.16.1.81:6379 0.0.0.0:* LISTEN 14345/../bin/redis- [root@redis01 /usr/local/redis/conf]# kill -9 14345 # 查看sentinel 82以變成主庫 127.0.0.1:26380> sentinel master mymaster 1) "name" 2) "mymaster" 3) "ip" 4) "172.16.1.82" 5) "port" 6) "6379" 7) "runid" 8) "007268419484bb9391e38ccf617fbbfaabc36fa0" 9) "flags" 10) "master" # 啓動主庫查看 [root@redis01 /usr/local/redis/conf]# ../bin/redis-server redis.conf # 已經變成從庫了 [root@redis01 /usr/local/redis/conf]# ../bin/redis-cli 127.0.0.1:6379> INFO replication 127.0.0.1:6379> AUTH 123 OK 127.0.0.1:6379> INFO replication # Replication role:slave master_host:172.16.1.82 master_port:6379 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_repl_offset:226331 # 查看哨兵日誌 [root@sentinel /usr/local/redis/conf]# tail sentinel_26380.log 11591:X 18 Dec 2020 20:47:33.491 * +slave-reconf-sent slave 172.16.1.83:6379 172.16.1.83 6379 @ mymaster 172.16.1.81 6379 11591:X 18 Dec 2020 20:47:34.460 * +slave-reconf-inprog slave 172.16.1.83:6379 172.16.1.83 6379 @ mymaster 172.16.1.81 6379 11591:X 18 Dec 2020 20:47:34.460 * +slave-reconf-done slave 172.16.1.83:6379 172.16.1.83 6379 @ mymaster 172.16.1.81 6379 # 81 檢測down掉 11591:X 18 Dec 2020 20:47:34.560 # -odown master mymaster 172.16.1.81 6379 11591:X 18 Dec 2020 20:47:34.560 # +failover-end master mymaster 172.16.1.81 6379 11591:X 18 Dec 2020 20:47:34.560 # +switch-master mymaster 172.16.1.81 6379 172.16.1.82 6379 # 82被從新選舉會主庫 11591:X 18 Dec 2020 20:47:34.560 * +slave slave 172.16.1.83:6379 172.16.1.83 6379 @ mymaster 172.16.1.82 6379 11591:X 18 Dec 2020 20:47:34.560 * +slave slave 172.16.1.81:6379 172.16.1.81 6379 @ mymaster 172.16.1.82 6379 11591:X 18 Dec 2020 20:48:04.594 # +sdown slave 172.16.1.81:6379 172.16.1.81 6379 @ mymaster 172.16.1.82 6379 11591:X 18 Dec 2020 20:49:07.859 # -sdown slave 172.16.1.81:6379 172.16.1.81 6379 @ mymaster 172.16.1.82 6379
#鏈接sentinel管理端口 [root@sentinel ~]# redis-cli -p 26380 #檢測狀態,返回PONG 127.0.0.1:26380> ping PONG #列出全部被監視的主服務器 127.0.0.1:26380> SENTINEL masters #列出全部被監視的從服務器 127.0.0.1:26380> SENTINEL slaves mymaster #返回給定名字的主服務器的IP地址和端口號 127.0.0.1:26380> SENTINEL get-master-addr-by-name mymaster 1) "172.16.1.51" 2) "6379 #重置全部名字和給定模式 127.0.0.1:26380> SENTINEL reset mymaster #當主服務器失效時,在不詢問其餘Sentinel意見的狀況下,強制開始一次自動故障遷移。 127.0.0.1:26380> SENTINEL failover mymaster
#查看81的權重 127.0.0.1:6379> CONFIG GET slave-priority 1) "slave-priority" 2) "100" #修改81的權重值爲0 127.0.0.1:6379> CONFIG set slave-priority 0 OK 127.0.0.1:6379> CONFIG GET slave-priority 1) "slave-priority" 2) "0" # 權重值越低越不會優先切換爲主庫
1.每10秒每一個sentinel會對master和slave執行info命令,這個任務達到兩個目的:
a)發現slave節點
b)確認主從關係服務器
2.每2秒每一個sentinel經過master節點的channel交換信息(pub/sub)。master節點上有一個發佈訂閱的頻道(sentinel:hello)。sentinel節點經過__sentinel__:hello頻道進行信息交換(對節點的"見解"和自身的信息),達成共識。網絡
3.每1秒每一個sentinel對其餘sentinel和redis節點執行ping操做(相互監控),這個實際上是一個心跳檢測,是失敗斷定的依據。架構
主觀下線
所謂主觀下線(Subjectively Down, 簡稱 SDOWN)指的是單個Sentinel實例對服務器作出的下線判斷,即單個sentinel認爲某個服務下線(有多是接收不到訂閱,之間的網絡不通等等緣由)。若是服務器在down-after-milliseconds給定的毫秒數以內, 沒有返回 Sentinel 發送的 PING 命令的回覆, 或者返回一個錯誤, 那麼 Sentinel 將這個服務器標記爲主觀下線(SDOWN )。sentinel會以每秒一次的頻率向全部與其創建了命令鏈接的實例(master,從服務,其餘sentinel)發ping命令,經過判斷ping回覆是有效回覆,仍是無效回覆來判斷實例時候在線(對該sentinel來講是「主觀在線」)。sentinel配置文件中的down-after-milliseconds設置了判斷主觀下線的時間長度,若是實例在down-after-milliseconds毫秒內,返回的都是無效回覆,那麼sentinel回認爲該實例已(主觀)下線,修改其flags狀態爲SRI_S_DOWN。若是多個sentinel監視一個服務,有可能存在多個sentinel的down-after-milliseconds配置不一樣,這個在實際生產中要注意。tcp
客觀下線
客觀下線(Objectively Down, 簡稱 ODOWN)指的是多個 Sentinel 實例在對同一個服務器作出 SDOWN 判斷, 而且經過 SENTINEL is-master-down-by-addr 命令互相交流以後, 得出的服務器下線判斷,而後開啓failover。ide
客觀下線就是說只有在足夠數量的 Sentinel 都將一個服務器標記爲主觀下線以後, 服務器纔會被標記爲客觀下線(ODOWN)。
只有當master被認定爲客觀下線時,纔會發生故障遷移。
當sentinel監視的某個服務主觀下線後,sentinel會詢問其它監視該服務的sentinel,看它們是否也認爲該服務主觀下線,接收到足夠數量(這個值能夠配置)的sentinel判斷爲主觀下線,既任務該服務客觀下線,並對其作故障轉移操做。
客觀下線條件只適用於主服務器: 對於任何其餘類型的 Redis 實例, Sentinel 在將它們判斷爲下線前不須要進行協商, 因此從服務器或者其餘 Sentinel 永遠不會達到客觀下線條件。只要一個 Sentinel 發現某個主服務器進入了客觀下線狀態, 這個 Sentinel 就可能會被其餘 Sentinel 推選出, 並對失效的主服務器執行自動故障遷移操。測試