前言
主從復制的實現在上一篇已經分享過,雖然主從復制本身的確讓讀寫分離更加高效,但是對於整體高可用存在很大的劣勢:當主節點宕機了之后還需要人為重新進行主從關系配置;這不是開玩笑嘛,這樣人為干預,故障恢復不及時,損失就難免啦。誰維護誰不爽,睡個覺都提心吊膽。
找個哨兵站崗,專門用來監控主服務器,一旦有變故,哨兵自動處理,這樣故障恢復及時且更加智能;接下來就來玩玩。
正文
Redis哨兵(Sentinel)其實本質就是一個RedisServer節點,通過設置運行模式來開啟哨兵的功能;主要功能如下:
- 監控(Monitoring):哨兵節點會不斷的檢查的主服務和從服務的運行狀態;
- 自動故障遷移(Automatic failover):當Redis主從模式中的主服務器發生故障時,哨兵節點會根據一定的策略自動進行故障遷移,即在原有主服務器下的從服務器中,自動選出一個從服務器作為新的主服務器,及時處理故障;
- 通知(Notification):當被監控的Redis服務器故障時,哨兵節點可以向相關人員或客戶端發送通知提醒;
- 配置提供者(Configuration provider):可以通過哨兵節點為客戶端提供主從模式中的主節點地址,這里的客戶端指平時寫的程序;
老規矩,還是先不說那么多理論,先來實操一把,然后再來總結:
哨兵模式搭建
先來個最基礎的:一個哨兵監控一主二從的環境;后面小伙伴就知道如何擴展啦,如下圖所示(這里通過一台機器演示,所以通過端口進行區分各個redis節點):
Redis哨兵模式是基於Redis主從復制的,所以先來搭建主從復制環境,這個過程在上一篇中已經詳細分享,這里就不細說,直接動手啦;
-
搭建主從復制環境,如上圖所示,6377作為主服務器,6388和6399作為從服務器,這里是通過配置文件的形式修改,最終效果如下:
-
主從復制環境搭建完畢之后,接下來需要有一個哨兵對其進行監控;之前有說過,Redis的功能通過配置文件就能快速實現,針對哨兵有一個單獨的配置文件,這里就起名為:sentinel.conf,內容如下:
sentinel monitor mymaster 127.0.0.1 6377 1
大概意思就是哨兵要監控對應的主服務器,其他啥都不用配置;
這里對於配置文件內容先不解釋這么多,接下來會專門進行介紹,先把環境搭建起來,玩一把再說;
-
啟動哨兵,兩種方式:
redis-sentinel啟動,redis-sentinel其實是用redis的一個代碼分支分離出來的,安裝完redis就有,命令如下:
./redis-sentinel ZoeConfig/sentinel.conf
redis-server啟動,指定為哨兵模式即可,命令如下:
./redis-server ZoeConfig/sentinel.conf --sentinel
啟動效果如下:
如上圖所示,Redis哨兵其實本質還是一個Redis節點,只是運行模式不一樣而已;
-
哨兵模式運行起來,模擬主服務器宕機,這里直接將6377服務器shutdown, 注意看哨兵打印的日志:
先將主服務器6377關掉,如下:
由於哨兵定時對主服務器進行監控,如果在30秒內(默認30秒)發現主服務器無法正常通訊時,就開始進行投票選舉原主服務器下的從服務器作為新主服務器,哨兵打印日志如下:
大概流程如下圖:
哨兵最后的狀態會持久化到指定的配置文件中,之前只是簡單配置了一條監控語句,現在如下:
-
驗證故障轉移結果;
光說6388變成了主服務器沒證據,連上6388看看,同時再看看6399有沒有換新主人,如下圖:
6388主從信息:
對應的配置文件中將之前的主從關系配置已經去掉了。
6399主從信息:
對應的配置文件也已經改了,如下:
以上就完成了哨兵模式搭建的演示啦,是不是很簡單,只要稍微改改配置文件即可完成自動化故障恢復。 到這小伙伴可能會問,原來故障的主服務器恢復了會怎么樣? 一個哨兵誤判主服務器下線或高並發抗不住怎么辦?嘿嘿嘿,接着來搞,接下來邊操作邊總結;
原故障的主服務器恢復之后只能當小兵
原有通訊異常的主服務器如果恢復正常,那它還能恢復原來的地位嗎?,還是另有安排呢?這個很好演示,直接將之前shutdown的主服務器重新起來即可;6377啟動后查看主從關系信息如下圖:
如上圖實操驗證,原來異常的主服務器(6377)恢復之后就變成新主服務器(6388)的從服務器了(原來再屌,現在也只是小弟,重新再混等機會)。
哨兵集群高可用
以上演示就一個哨兵,這樣有很明顯的兩個缺點,如下:
- 單個哨兵容易導致誤判主節點下線,比如主節點正常,只是在與哨兵之間通訊出現短暫異常,如果是單個哨兵,在指定的時間間隔沒有通訊就認為主節點下線了,但其實沒有;如果哨兵集群,可以詢問多個哨兵指定的主節點是否下線,這樣就顯得更有保障;
- 哨兵掛了,故障轉移就沒法繼續啦,哨兵集群的話就會選擇其他哨兵繼續處理;
配置哨兵集群超級簡單,就是增加節點即可,哨兵節點會通過發布與訂閱功能來自動發現正在監視相同主服務器的其他哨兵 , 這一功能是通過向頻道 sentinel:hello 發送信息來實現的。如下圖再新增一個哨兵節點,同時增加一個配置文件,由於默認端口為26379,上一個哨兵已經占用,這里在新增的配置文件中指定新哨兵的端口為:26388;
配置文件名為sentinel26388.conf,內容如下:
sentinel monitor mymaster 127.0.0.1 6388 1
port 26388
指定配置文件啟動第二個哨兵,啟動命令為./redis-sentinel ZoeConfig/sentinel26388.conf
,效果如下:
哨兵如何做到互相交流和監控從服務器的
到這應該有小伙伴會有疑問:在配置哨兵的時候,只配置監控主服務器,從服務器是怎么知道的?哨兵之間的交流是通過什么形式實現的?
關於從服務器: 哨兵會自動詢問主服務器獲得對應從服務器的信息,因為從服務器會在連接主服務器的時候把相關信息給主服務器,所以哨兵能通過主服務器拿到從服務器的信息;
關於哨兵之間:哨兵節點會通過發布與訂閱功能來自動發現正在監視相同主服務器的其他哨兵 , 這一功能是通過向頻道 sentinel:hello 發送信息來實現的;
注:一個哨兵可以同時監控多個主服務器;
哨兵配置文件介紹
以上配置只是為了快速實現演示,其實關於哨兵還有其他很多配置,接下來都過一遍:
-
port:哨兵的端口,默認是26379,可以通過此配置項進行修改;
-
dir:哨兵的工作目錄;
-
sentinel monitor
: master-name:對監控的節點進行命名,方便后續根據名稱獲取信息;
ip:主節點ip;
redis-port:主節點的端口;
quorum:整數,及設置有幾個哨兵統一認為主節點下線為條件,滿足這個數量就將主節點標記為客觀下線;
例:sentinel monitor mymaster 127.0.0.1 6388 2,意思就是當有兩個哨兵都認為監控的mymaster主節點下線了,就將此主節點標記為客觀下線;則可以進行下一步故障轉移操作了;
-
sentinel auth-pass
: -
sentinel down-after-milliseconds
: -
sentinel parallel-syncs
: -
sentinel failover-timeout
: -
sentinel notification-script
:
連接哨兵常用的命令
-
info sentinel:獲取監控的主節點信息;
-
sentinel masters:獲取監控主節點的詳細信息;
-
sentinel master <監控時設置的名稱>:上面我們指定的是mymaster,信息和上面類似;
-
sentinel get-master-addr-by-name <監控時設置的名稱>:根據指定的名稱獲取ip地址和端口信息,上面我們指定的名稱是mymaster;
-
sentinel is-master-down-by-addr:查看監控的主節點是否下線,哨兵之間判斷主節點是否下線原理就是通過此命令;
-
sentinel slaves <監控時設置的名稱>:獲取監控主節點的從節點信息;上面我們指定的是mymaster
-
sentinel failover <監控時設置的名稱>:該命令可以強制對指定監控執行故障轉移,即便當前的主節點運行完好也能執行;例如,需要換掉當前監控的主節點,便可以提前通過failover命令進行故障轉移;上面我們指定的名稱是mymaster;
總結
主從復制加個哨兵看似很完美啦,但仔細想想,雖然讀寫分離分開了,但寫還是單節點,如果寫的並發量特別大怎么辦,那肯定扛不住,所以這下集群該出山了,下一次聊聊redis集群;
一個被程序搞丑的帥小伙,關注"Code綜藝圈",跟我一起學~~~