一文掌握Redis的哨兵Sentinel原理到實戰

一、爲什麼要有Sentinel

是因爲我們上篇主從複製中也發現了Master掛了後需要人工去升級Slave爲Master,然後讓其他Slave作爲新升級Master的S,這整個過程都是人爲操作的。所以並不是真正意義的高可用,因爲機器過多你可能切換半小時,Sentinel就是爲了解放人類的,全自動升級Master等一系列操作,這纔是真正意義的高可用!

對主從複製以及我說的人工切換的描述不清晰的,請看
一文掌握Redis的主從複製原理到實戰

二、什麼是Sentinel

sentinel可以認爲是一個負責監控的和自動故障轉移的一個哨兵,也就是門衛,我時刻守護着大門,出問題我就及時發現,然後自動故障修復(S升級爲M)。所以啓動腳本里會指定–sentinel參數來告訴Redis此進程不再是一個存儲kv的存儲引擎,而是一個哨兵。

三、該升級誰爲M

問題:Master掛了,該升級哪個Slave爲新的Master呢?

一般規定,也建議設置爲Redis主從個數的一半以上(也就是2/n + 1),比如1主2從,那就設置爲2,1主3從就設置爲3,一主4從就設置爲3(5 / 2 + 1 = 3)。

疑問:爲什麼是2/n+1?

因爲如果
1.全部哨兵同意才能升級的話,也就是比如3個Redis、3個Redis哨兵必須保證3個哨兵都同意A節點升級爲Master纔行的話,那很可能第一臺哨兵由於自身網絡問題導致連接失敗,而其他兩個都是正常的,那就不升級了?不公平也不合適,因爲那個哨兵明明是自身網絡問題。
2.一個哨兵同意就升級的話,也就是比如3個Redis、3個Redis哨兵只要保證又1個哨兵都同意A節點升級爲Master就可以的話,那也不靠譜,很可能那節點已經掛了,但是哨兵A可能緩存或者其他問題返回正常,但是其他兩個哨兵明顯發現問題連接不上了等,少數服從多數是最保險最靠譜的。最主要的是一個哨兵同意就可以的話會產生腦裂問題。

三、什麼是腦裂

腦子裂開了,一分爲二。也就是形容一個Master由於腦裂變成了2個Master的情況。具體如下:
如果1個Master3個Slave組成的哨兵模式(哨兵獨立部署到其他機器上的),恰巧這時候Master與3個Slave和其中某1個哨兵之間的網絡發生故障,但是Slave和哨兵之間通訊正常。那麼如果設置1個哨兵同意就升級的話恰巧這個Master無法通信的哨兵同意了一個Slave升級,然後就升級了,那麼這時候就會存在兩個Master,因爲之前的Master並沒有掛掉,只是和你這個哨兵通信不了,和其他的照常。這時候就會造成客戶端請求寫的話會落到升級之前的Master上,但這個M又沒法給Slave同步數據,導致問題。但並不是2/n+1個同意就沒腦裂了,只是不易出現了。根治的辦法需要這兩個參數

# 表示連接到master的最少slave數量
min-replicas-to-write 3
# 表示slave連接到master的最大延遲時間
min-replicas-max-lag 10

按照上面的配置,要求至少3個slave節點,且數據複製和同步的延遲不能超過10秒,否則的話master就會拒絕寫請求,配置了這兩個參數之後,如果發生集羣腦裂,原先的master節點接收到客戶端的寫入請求會拒絕,就可以減少數據同步之後的數據丟失。

四、實操

官網很權威:http://redis.cn/topics/sentinel.html

(1)先啓動三臺Redis,1M2S

這塊不懂的轉到一文掌握Redis的主從複製原理到實戰

redis-server /etc/redis/6379.conf
redis-server /etc/redis/6380.conf  --replicaof localhost 6379
redis-server /etc/redis/6381.conf  --replicaof localhost 6379

(2)創建三個哨兵

創建哨兵的方法:sentinel <選項的名字> <主服務器的名字> <選項的值>

# 新建26379.config

# 當前哨兵的端口號
port 26379
# 監聽Master,最後的2代表上面的:該升級誰爲M中的2/n+1,因爲3個機器,所以這裏是2
sentinel monitor mymaster 127.0.0.1 6379 2
# 新建26380.config

# 當前哨兵的端口號
port 26380
sentinel monitor mymaster 127.0.0.1 6379 2
# 新建26381.config

# 當前哨兵的端口號
port 26381
sentinel monitor mymaster 127.0.0.1 6379 2

(3)啓動哨兵

# --sentinel 告訴他你不是一個存儲kv的存儲引擎了,而是一個哨兵負責監控的
redis-server /etc/redis/26379.conf --sentinel

在這裏插入圖片描述

# --sentinel 告訴他你不是一個存儲kv的存儲引擎了,而是一個哨兵負責監控的
redis-server /etc/redis/26380.conf --sentinel

在這裏插入圖片描述

這裏會多出來一個26379的哨兵,因爲上面在【該升級誰爲M】中說了,三個哨兵,兩個同意A升級 ,那就A升級爲M,所以這三個哨兵之間是需要通信的。 這時候再去看剛啓動的26379的哨兵的log,也會多出一個26380的哨兵來。
在這裏插入圖片描述

# --sentinel 告訴他你不是一個存儲kv的存儲引擎了,而是一個哨兵負責監控的
redis-server /etc/redis/26381.conf --sentinel

在這裏插入圖片描述

會發現多出來2個哨兵,分別是26379/26380,同理,回過去看26379和26380的log也會多出26381這個哨兵。

(4)Redis和哨兵都啓動完了,進行測試

幹掉6379的Redis,讓他停止進程。看是否會從6380/6381中選舉出來一個作爲Master,然後另一個是否會自動作爲當前選出來的這個Master的Slave。

出現的結果是6380和6381會報錯,因爲找不到Master了,大概10s左右會自動選擇一個Slave作爲新的Master
爲什麼不立馬選舉要等10s左右?因爲這10S內可能M又恢復了,這時候繼續M作爲M。網絡延遲或者異常重啓也可能,所以不立馬切換。
如果Slave自動升級成Master後(3個哨兵2個同意6380升級,那就6380。),另外一個Slave會作爲新Master的從,剛掛了的主啓動後也會自動作爲新Master的Slave。
在這裏插入圖片描述

從log中可以發現6380升級爲新M,且執行slaveof noone,這個命令就代表是升級爲M的。6380是兩個哨兵選舉出來的。

疑問:哨兵的配置文件寫死的6379是Master,還需要手動一個一個的改?
答案:不需要,自動升級和切換完成後,哨兵配置文件會自動被修改。完全解放人力。

(5)補充:哨兵之間是怎麼彼此發現的?

上面啓動哨兵的時候從log中能發現彼此是感知的,怎麼做的?

是通過PSUBSCRIBE這個Redis內置的發佈訂閱來實現的。我們可以開個客戶端簡單看下

redis-cli
# 這裏就*,便於測試
PSUBSCRIBE *

可以發現結果都是26379/26380/26381三者再交互,就是這麼實現哨兵之間彼此發現的
在這裏插入圖片描述

五、總結

其實哨兵就是實現HA高可用的,自動故障修復。而不是人力。

六、個人公衆號

微信公衆號【Java碼農社區】
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章