Redis從菜鳥到大神-Sentinel哨兵模式

一、Redis哨兵方案

目前我們講的 Redis 還只是主從方案,最終一致性。讀者們可思考過,如果主節點凌晨 3 點突發宕機怎麼辦?就坐等運維從牀上爬起來,然後手工進行從主切換,再通知所有的程 序把地址統統改一遍重新上線麼?毫無疑問,這樣的人工運維效率太低,事故發生時估計得 至少 1 個小時才能緩過來。如果是一個大型公司,這樣的事故足以上新聞了。

所以我們必須有一個高可用方案來抵抗節點故障,當故障發生時可以自動進行從主切 換,程序可以不用重啓,運維可以繼續睡大覺,彷彿什麼事也沒發生一樣。Redis 官方提供 了這樣一種方案 —— Redis Sentinel(哨兵)。

我們可以將 Redis Sentinel 集羣看成是一個 ZooKeeper 集羣,它是集羣高可用的心臟, 它一般是由 3~5 個節點組成,這樣掛了個別節點集羣還可以正常運轉。

它負責持續監控主從節點的健康,當主節點掛掉時,自動選擇一個最優的從節點切換爲 主節點。

客戶端來連接集羣時,會首先連接 sentinel,通過 sentinel 來查詢主節點的地址, 然後再去連接主節點進行數據交互。

當主節點發生故障時,客戶端會重新向 sentinel 要地址,sentinel 會將最新的主節點地址告訴客戶端。

如此應用程序將無需重啓即可自動完成節 點切換。比如上圖的主節點掛掉後,集羣將可能自動調整爲下圖所示結構。

從這張圖中我們能看到主節點掛掉了,原先的主從複製也斷開了,客戶端和損壞的主節 點也斷開了。從節點被提升爲新的主節點,其它從節點開始和新的主節點建立複製關係。客 戶端通過新的主節點繼續進行交互。Sentinel 會持續監控已經掛掉了主節點,待它恢復後, 集羣會調整爲下面這張圖。

此時原先掛掉的主節點現在變成了從節點,從新的主節點那裏建立複製關係。

二、哨兵主從切換消息丟失

Redis 主從採用異步複製,意味着當主節點掛掉時,從節點可能沒有收到全部的同步消 息,這部分未同步的消息就丟失了。如果主從延遲特別大,那麼丟失的數據就可能會特別 多。Sentinel 無法保證消息完全不丟失,但是也儘可能保證消息少丟失。它有兩個選項可以 限制主從延遲過大。

min-slaves-to-write 1

min-slaves-max-lag 10

  第一個參數表示主節點必須至少有一個從節點在進行正常複製,否則就停止對外寫服
務,喪失可用性。

何爲正常複製,何爲異常複製?這個就是由第二個參數控制的,它的單位是秒,表示如 果 10s 沒有收到從節點的反饋,就意味着從節點同步不正常,要麼網絡斷開了,要麼一直沒 有給反饋。

四、客戶端連接池如何感知地址變更

有個問題是,但 sentinel 進行主從切換時,客戶端如何知道地址變更了 ? 通過分析源 碼,我發現 redis-py 在建立連接的時候進行了主庫地址變更判斷。

  連接池建立新連接時,會去查詢主庫地址,然後跟內存中的主庫地址進行比對,如果變
更了,就斷開所有連接,重新使用新地址建立新連接。如果是舊的主庫掛掉了,那麼所有正
在使用的連接都會被關閉,然後在重連時就會用上新地址。

但是這樣還不夠,如果是 sentinel 主動進行主從切換,主庫並沒有掛掉,而之前的主庫 連接已經建立了在使用了,沒有新連接需要建立,那這個連接是不是一致切換不了?

繼續深入研究源碼,我發現 redis-py 在另外一個點也做了控制。那就是在處理命令的時 候捕獲了一個特殊的異常 ReadOnlyError,在這個異常裏將所有的舊連接全部關閉了,後續指 令就會進行重連。

主從切換後,之前的主庫被降級到從庫,所有的修改性的指令都會拋出 ReadonlyError。 如果沒有修改性指令,雖然連接不會得到切換,但是數據不會被破壞,所以即使不切換也沒 關係。

 

———————————————————————————————————

參考文章:https://blog.csdn.net/shenchaohao12321/article/details/87955028

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