Redis Sentinel(哨兵)是Redis官方提供的高可用性(HA)解決方案,用于管理Redis主從架構并實現自動故障轉移。
一、集群結構和作用
哨兵是一個分布式系統,由多個哨兵節點組成:
哨兵的作用如下:
監控:Sentinel 會不斷檢查您的master和slave是否按預期工作
自動故障恢復:如果master故障,Sentinel會將一個slave提升為master。當故障實例恢復后也以新的master為主
通知:Sentinel充當Redis客戶端的服務發現來源,當集群發生故障轉移時,會將最新信息推送給Redis的客戶端
二、哨兵工作原理
Sentinel基于心跳機制監測服務狀態,每隔1秒向集群的每個實例發送ping命令:
- 主觀下線:如果某sentinel節點發現某實例未在規定時間響應,則認為該實例主觀下線。
- 客觀下線:若超過指定數量(quorum)的sentinel都認為該實例主觀下線,則該實例客觀下線。quorum值最好超過Sentinel實例數量的一半。
三、集群故障恢復原理
1.哨兵選主規則
一旦發現master故障,sentinel需要在salve中選擇一個作為新的master,選擇依據是這樣的:
首先會判斷slave節點與master節點斷開時間長短,如果超過指定值(down-after-milliseconds * 10)則會排除該slave節點
然后判斷slave節點的slave-priority值,越小優先級越高,如果是0則永不參與選舉
如果slave-prority一樣,則判斷slave節點的offset值,越大說明數據越新,優先級越高
最后是判斷slave節點的運行id大小,越小優先級越高。
2.故障轉移流程
當選出一個新的master后,該如何實現切換呢?
流程如下:
sentinel給備選的slave1節點發送slaveof no one命令,讓該節點成為master
sentinel給所有其它slave發送slaveof 192.168.206.180?7002 命令,讓這些slave成為新master的從節點,開始從新的master上同步數據。
最后,sentinel將故障節點標記為slave,當故障節點恢復后會自動成為新的master的slave節點
四、Docker搭建Redis哨兵集群
五、相關面試問題
1.怎么保證redis的高并發高可用?
? ? ? ? redis提供了主從同步+哨兵模式保證了redis的高并發和高可用性。
? ? ? ? 首先,主從同步保證了redis的高并發性:單節點redis的并發能力是有上線的,我們可以搭建主從同步集群實現redis的讀寫分離:master負責寫數據,slave只負責讀數據。
? ? ? ? 然后,哨兵機制保證了redis的高可用性:哨兵機制可以實現主從集群的自動故障恢復,里面就包含了對主從服務的檢測、自動故障恢復和通知;如果master故障,sentinel會重新選取一個slave作為新的master,當master恢復會自動下降為slave。同時當redis實現故障轉移,sentinel會向redis客戶端通知信息變化。
2.如何解決redis的集群腦裂問題
? ? ? ? redis的哨兵模式一般會因為網絡等原因出現腦裂問題。也就是,master、slave和sentinel處于不同的網絡分區,sentinel心跳機制檢測不到master,會重新選舉一個slave作為新的master,但是舊的master并未下線,仍在寫入數據,新的master無法同步,當網絡恢復,舊的master下降為slave,就會導致丟失大量數據。
? ? ? ? 我知道的有以下幾種方法可以避免和減輕腦裂問題:
? ? ? ? 第一,設置合適的哨兵quonum,一般為N/2+1(其中N為哨兵節點數)。
? ? ? ? 第二,啟用主節點寫入保護,在redis.conf中添加:至少要有1個從節點連接(min-slaves-to-write 1)和從節點復制延遲不超過10秒(min-slaves-max-lag 10)才能同步數據。