一、故障轉移日誌
- 開始故障轉移測試,模擬故障的方法有很多,比較典型的方法有以下幾種:
- 方法一,強制殺掉對應節點的進程號,這樣可以模擬出宕機的效果
- 方法二,使用Redis的debug sleep命令,讓節點進入睡眠狀態,這樣可 以模擬阻塞的效果
- 方法三,使用Redis的shutdown命令,模擬正常的停掉Redis
- 本次我們使用方法一進行測試,因爲從實際經驗來看,數百上千臺機器偶爾宕機一兩臺是會不定期出現的,爲了方便分析日誌行爲,這裏記錄一下操作的時間和命令
- 用kill-9使主節點的進程宕機,操作時間2016-07-2409:40:35:
kill -9 19661
- 觀察效果:6380節點晉升爲主節點,6381節點成爲6380節點的從節點
6379節點日誌
- 兩個複製請求,分別來自端口爲6380和6381的從節點:
- 09:40:35做了kill-9操作,由於模擬的是宕機效果,所以6379節點沒有看到任何日誌(這點和shutdown操作不太相同)
6380節點日誌
- 6380節點在09:40:35之後發現它與6379節點已經失聯:
- 09:41:06時它接到Sentinel節點的命令:清理原來緩存的主節點狀態,Sentinel節點將6380節點晉升爲主節點,並重寫配置:
6381節點日誌
- 後續操作如下:
- 1)09:41:06時它接到Sentinel節點的命令,清理原來緩存的主節點狀 態,讓它去複製新的主節點(6380節點):
sentinel-1節點日誌
- 09:41:05對6379節點作了主觀下線(+sdown),注意這個時間正好 是kill-9後的30秒,和down-after-milliseconds的配置是一致的。Sentinel節點更新自己的配置紀元(new-epoch):
- 後續操作如下:
- 1)投票給sentinel-3節點:
- 2)更新狀態:從sentinel-3節點(領導者)得知:故障轉移後6380節點變爲主節點,並發現了兩個從節點6381和6379,並在30秒後對(09:41: 07~09:41:37)6379節點做了主觀下線:
sentinel-2節點日誌
- 整個過程和sentinel-1節點是一樣的,這裏就不介紹了
sentinel-3節點日誌
- 從sentinel-1節點和sentinel-2節點的日誌來看,sentinel-3節點是領導者, 所以分析sentinel-3節點的日誌至關重要
- 後續操作如下
- 1)達到了客觀下線的條件:
- 下圖展示了3個Sentinel節點完成客觀下線的時間點,從時間點可以看 到sentinel-3節點最先完成客觀下線
- 3)故障轉移。每一步都可以通過發佈訂閱來獲取,對於每個字段的說明可以參考下面的介紹
- 尋找合適的從節點作爲新的主節點:
- 命令6380節點執行slaveof no one,使其成爲主節點:
- 6381節點正在重新配置成爲6380節點的從節點,但是同步過程尚未完 成:
原主節點後續處理
- 重新啓動原來的6379節點:
- (1)6379節點:啓動後接到Sentinel節點的命令,讓它去複製6380節點:
- (2)6380節點:接到6379節點的複製請求,做複製的相應處理:
- (3)sentinel-1節點日誌:撤銷對6379節點主觀下線的決定:
- (4)sentinel-2節點日誌:撤銷對6379節點主觀下線的決定:
- (5)sentinel-3節點日誌:撤銷對6379節點主觀下線的決定,更新Sentinel節點配置:
- 下圖記錄了Redis Sentinel在故障轉移一些重要的事件消息對應的頻道:
- 注意點:部署各個節點的機器時間儘量要同步,否則日誌的時序性會混亂,例如可以給機器添加NTP服務來同步時間,具體可以參考後面“Linux配置”相關文章
二、節點運維
①節點下線
- 臨時下線和永久下線:
- 臨時下線:暫時將節點關掉,之後還會重新啓動,繼續提供服務
- 永久下線:將節點關掉後不再使用,需要做一些清理工作,如刪除配 置文件、持久化文件、日誌文件
- 無論是主節點、從節點還是Sentinel節點,下線原因無外乎以下幾種:
- 節點所在的機器出現了不穩定或者即將過保被回收
- 節點所在的機器性能比較差或者內存比較小,無法支撐應用方的需 求
- 節點自身出現服務不正常情況,需要快速處理
主節點下線處理
- 如果需要對主節點進行下線,比較合理的做法是選出一個“合適”(例如性能更高的機器)的從節點,使用sentinel failover功能將從節點晉升主節點,只需要在任意可用的Sentinel節點執行如下操作即可:
sentinel failover <master name>
從節點和Sentinel節點下線處理
- 如果需要對從節點或者Sentinel節點進行下線,只需要確定好是臨時還是永久下線後執行相應操作即可。如果使用了讀寫分離,下線從節點需要保證應用方可以感知從節點的下線變化,從而把讀取請求路由到其他節點
- 需要注意的是,Sentinel節點依然會對這些下線節點進行定期監控,這是由Redis Sentinel的設計思路所決定的。下面日誌顯示(需要設置 loglevel=debug),6380節點下線後,Sentinel節點還是會定期對其監控,會造成一定的網絡資源浪費
節點上線
添加從節點
- 添加從節點的場景大致有如下幾種:
- 使用了讀寫分離,但現有的從節點無法支撐應用方的流量
- 主節點沒有可用的從節點,無法支持故障轉移
- 添加一個更強悍的從節點利用手動failover替換主節點。
- 添加方法:添加slaveof {masterIp} {masterPort}的配置,使用redis-server啓動即可,它將被Sentinel節點自動發現
添加Sentinel節點
- 添加Sentinel節點的場景可以分爲以下幾種:
- 當前Sentinel節點數量不夠,無法達到Redis Sentinel健壯性要求或者無 法達到票數
- 原Sentinel節點所在機器需要下線
- 添加方法:添加sentinel monitor主節點的配置,使用redis-sentinel啓動即 可,它將被其餘Sentinel節點自動發現
節點配置
- 有關Redis數據節點和Sentinel節點配置修改以及優化的方法,前面的文章已經介紹過了,這裏給出Sentinel節點配置時要注意的地方:
- Sentinel節點配置儘可能一致,這樣在判斷節點故障時會更加準確
- Sentinel節點支持的命令非常有限,例如config命令是不支持的,而 Sentinel節點也需要dir、loglevel之類的配置,所以儘量在一開始規劃好,不 過所幸Sentinel節點不存儲數據,如果需要修改配置,重新啓動即可。
- 運維提示:Sentinel節點只支持如下命令:ping、sentinel、subscribe、unsubscribe、 psubscribe、punsubscribe、publish、info、role、client、shutdown。
- 具體可以參考源碼中sentinel.c
三、高可用讀寫分離
從節點的作用
- 從節點一般可以起到兩個作用:
- 第一,當主節點出現故障時,作爲主節點的後備“頂”上來實現故障轉移,Redis Sentinel已經實現了該功能的自動化,實現了真正的高可用
- 第二,擴展主節點的讀能力,尤其是在讀多寫少的場景非常適用,通常的模型如下圖所示
- 但上述模型中,從節點不是高可用的:
- 如果slave-1節點出現故障,首先客戶端client-1將與其失聯,其次Sentinel節點只會對該節點做主觀下線,因爲Redis Sentinel的故障轉移是針對主節點的
- 所以很多時候,Redis Sentinel中的從節點僅僅是作爲主節點一個熱備,不讓它參與客戶端的讀操作,就是爲了保證整體高可用性,但實際上這種使用方法還是有一些浪費,尤其是在有很多從節點或者確實需要讀寫分離的場景,所以如何實現從節點的高可用是非常有必要的
Redis Sentinel讀寫分離設計思路
- Redis Sentinel在對各個節點的監控中,如果有對應事件的發生,都會發出相應的事件消息(詳情見上面“Sentinel發佈訂閱頻道”圖片),其中和從節點變動的事件有以下幾個:
- +switch-master:切換主節點(原來的從節點晉升爲主節點),說明減少了某個從節點
- +convert-to-slave:切換從節點(原來的主節點降級爲從節點),說明添加了某個從節點
- +sdown:主觀下線,說明可能某個從節點可能不可用(因爲對從節點不會做客觀下線),所以在實現客戶端時可以採用自身策略來實現類似主觀 下線的功能
- +reboot:重新啓動了某個節點,如果它的角色是slave,那麼說明添加了某個從節點
- 所以在設計Redis Sentinel的從節點高可用時,只要能夠實時掌握所有從節點的狀態,把所有從節點看做一個資源池(如下圖所示),無論是上線還是下線從節點,客戶端都能及時感知到(將其從資源池中添加或者刪除),這樣從節點的高可用目標就達到了