1. 程式人生 > >跟我一起學Redis之加個哨兵讓主從複製更加高可用

跟我一起學Redis之加個哨兵讓主從複製更加高可用

### 前言 主從複製的實現在[上一篇](https://mp.weixin.qq.com/s?__biz=MzU1MzYwMjQ5MQ==&mid=2247484394&idx=1&sn=12eec9feea7ecd4e21c474fa1b146366&chksm=fbf11f3ecc869628bf494ccd896237f8649698cce8a952c2ed98b7f73afd1307129f6a5d6c22&token=1364939791&lang=zh_CN#rd)已經分享過,雖然主從複製本身的確讓讀寫分離更加高效,但是對於整體高可用存在很大的劣勢:當主節點宕機了之後還需要人為重新進行主從關係配置;這不是開玩笑嘛,這樣人為干預,故障恢復不及時,損失就難免啦。誰維護誰不爽,睡個覺都提心吊膽。 找個哨兵站崗,專門用來監控主伺服器,一旦有變故,哨兵自動處理,這樣故障恢復及時且更加智慧;接下來就來玩玩。 ### 正文 **Redis哨兵(Sentinel)**其實本質就是一個RedisServer節點,通過設定**執行模式**來開啟哨兵的功能;主要功能如下: - **監控(Monitoring**):哨兵節點會不斷的檢查的主服務和從服務的執行狀態; - **自動故障遷移(Automatic failover)**:當Redis主從模式中的主伺服器發生故障時,哨兵節點會根據一定的策略自動進行故障遷移,即在原有主伺服器下的從伺服器中,自動選出一個從伺服器作為新的主伺服器,及時處理故障; - **通知(Notification)**:當被監控的Redis伺服器故障時,哨兵節點可以向相關人員或客戶端傳送通知提醒; - **配置提供者(Configuration provider)**:可以通過哨兵節點為客戶端提供主從模式中的主節點地址,這裡的客戶端指平時寫的程式; 老規矩,還是先不說那麼多理論,先來實操一把,然後再來總結: #### 哨兵模式搭建 先來個最基礎的:一個哨兵監控一主二從的環境;後面小夥伴就知道如何擴充套件啦,如下圖所示(這裡通過一臺機器演示,所以通過埠進行區分各個redis節點): ![image-20210114141345708](https://i.loli.net/2021/01/14/S46Fj3t8EzD9KoY.png) Redis哨兵模式是基於Redis主從複製的,所以先來搭建主從複製環境,這個過程在[上一篇](https://mp.weixin.qq.com/s?__biz=MzU1MzYwMjQ5MQ==&mid=2247484394&idx=1&sn=12eec9feea7ecd4e21c474fa1b146366&chksm=fbf11f3ecc869628bf494ccd896237f8649698cce8a952c2ed98b7f73afd1307129f6a5d6c22&token=1364939791&lang=zh_CN#rd)中已經詳細分享,這裡就不細說,直接動手啦; 1. 搭建主從複製環境,如上圖所示,6377作為主伺服器,6388和6399作為從伺服器,這裡是通過配置檔案的形式修改,最終效果如下: ![image-20210114142426244](https://i.loli.net/2021/01/14/a7FCS1iceUVMBrE.png) 2. 主從複製環境搭建完畢之後,接下來需要有一個哨兵對其進行監控;之前有說過,Redis的功能通過配置檔案就能快速實現,針對哨兵有一個單獨的配置檔案,這裡就起名為:**sentinel.conf**,內容如下: ```sentinel monitor mymaster 127.0.0.1 6377 1``` 大概意思就是哨兵要監控對應的主伺服器,其他啥都不用配置; 這裡對於配置檔案內容先不解釋這麼多,接下來會專門進行介紹,先把環境搭建起來,玩一把再說; 3. 啟動哨兵,兩種方式: **redis-sentinel啟動**,redis-sentinel其實是用redis的一個程式碼分支分離出來的,安裝完redis就有,命令如下: ```./redis-sentinel ZoeConfig/sentinel.conf``` **redis-server啟動**,指定為哨兵模式即可,命令如下: ```./redis-server ZoeConfig/sentinel.conf --sentinel``` 啟動效果如下: ![image-20210114164300813](https://i.loli.net/2021/01/14/loWgyVp4JhHPxcT.png) 如上圖所示,Redis哨兵其實本質還是一個Redis節點,只是執行模式不一樣而已; 4. 哨兵模式執行起來,模擬主伺服器宕機,這裡直接將6377伺服器shutdown, 注意看哨兵列印的日誌: 先將主伺服器6377關掉,如下: ![image-20210114165824631](https://i.loli.net/2021/01/14/RKWqekpyfUNPlbD.png) 由於哨兵定時對主伺服器進行監控,如果在30秒內(預設30秒)發現主伺服器無法正常通訊時,就開始進行投票選舉原主伺服器下的從伺服器作為新主伺服器,哨兵列印日誌如下: ![image-20210114170909938](https://i.loli.net/2021/01/14/BOxZ5lSrmjgKTY6.png) 大概流程如下圖: ![image-20210115105820011](https://i.loli.net/2021/01/15/YqAh2QEuv4RnmMZ.png) 哨兵最後的狀態會持久化到指定的配置檔案中,之前只是簡單配置了一條監控語句,現在如下: ![image-20210115122612914](https://i.loli.net/2021/01/15/xOUodmnZEAeJGIs.png) 5. 驗證故障轉移結果; 光說6388變成了主伺服器沒證據,連上6388看看,同時再看看6399有沒有換新主人,如下圖: **6388主從資訊**: ![image-20210114171247927](https://i.loli.net/2021/01/14/3XzTvs7L6oaRVgD.png) 對應的配置檔案中將之前的主從關係配置已經去掉了。 **6399主從資訊**: ![image-20210114171516670](https://i.loli.net/2021/01/14/HOvrR4DiJxFhYSo.png) 對應的配置檔案也已經改了,如下: ![image-20210114171713342](https://i.loli.net/2021/01/14/yeYrFmua1HUO32f.png) 以上就完成了哨兵模式搭建的演示啦,是不是很簡單,只要稍微改改配置檔案即可完成自動化故障恢復。 到這小夥伴可能會問,原來故障的主伺服器恢復了會怎麼樣? 一個哨兵誤判主伺服器下線或高併發抗不住怎麼辦?嘿嘿嘿,接著來搞,接下來邊操作邊總結; #### 原故障的主伺服器恢復之後只能當小兵 原有通訊異常的主伺服器如果恢復正常,那它還能恢復原來的地位嗎?,還是另有安排呢?這個很好演示,直接將之前shutdown的主伺服器重新起來即可;6377啟動後檢視主從關係資訊如下圖: ![image-20210115111608936](https://i.loli.net/2021/01/15/jbfrxTRk8FZ2sna.png) 如上圖實操驗證,原來異常的主伺服器(6377)恢復之後就變成新主伺服器(6388)的從伺服器了(原來再屌,現在也只是小弟,重新再混等機會)。 #### 哨兵叢集高可用 以上演示就一個哨兵,這樣有很明顯的兩個缺點,如下: - 單個哨兵容易導致誤判主節點下線,比如主節點正常,只是在與哨兵之間通訊出現短暫異常,如果是單個哨兵,在指定的時間間隔沒有通訊就認為主節點下線了,但其實沒有;如果哨兵叢集,可以詢問多個哨兵指定的主節點是否下線,這樣就顯得更有保障; - 哨兵掛了,故障轉移就沒法繼續啦,哨兵叢集的話就會選擇其他哨兵繼續處理; 配置哨兵叢集超級簡單,就是增加節點即可,哨兵節點會通過釋出與訂閱功能來自動發現正在監視**相同主伺服器**的其他哨兵 , 這一功能是通過向頻道 **sentinel**:hello 傳送資訊來實現的。如下圖再新增一個哨兵節點,同時增加一個配置檔案,由於預設埠為26379,上一個哨兵已經佔用,這裡在新增的配置檔案中指定新哨兵的埠為:26388; 配置檔名為**sentinel26388.conf**,內容如下: ``` bash sentinel monitor mymaster 127.0.0.1 6388 1 port 26388 ``` 指定配置檔案啟動第二個哨兵,啟動命令為``` ./redis-sentinel ZoeConfig/sentinel26388.conf ```,效果如下: ![image-20210115123029803](https://i.loli.net/2021/01/15/9Yd1JyvWzpX8IbF.png) #### 哨兵如何做到互相交流和監控從伺服器的 到這應該有小夥伴會有疑問:在配置哨兵的時候,只配置監控主伺服器,從伺服器是怎麼知道的?哨兵之間的交流是通過什麼形式實現的? **關於從伺服器:** 哨兵會自動詢問主伺服器獲得對應從伺服器的資訊,因為從伺服器會在連線主伺服器的時候把相關資訊給主伺服器,所以哨兵能通過主伺服器拿到從伺服器的資訊; **關於哨兵之間:**哨兵節點會通過釋出與訂閱功能來自動發現正在監視**相同主伺服器**的其他哨兵 , 這一功能是通過向頻道 **sentinel**:hello 傳送資訊來實現的; 注:一個哨兵可以同時監控多個主伺服器; #### 哨兵配置檔案介紹 以上配置只是為了快速實現演示,其實關於哨兵還有其他很多配置,接下來都過一遍: - **port:**哨兵的埠,預設是26379,可以通過此配置項進行修改; - **dir:**哨兵的工作目錄; - **sentinel