Redis哨兵(sentinel)為redis提供高可用解決方案,在傳統的主從複製模式中,當主節點宕機後,我們需要手動將從節點切換成主節點,並且客戶端也需要同步修改配置文件中的主節點信息,當哨兵模式啟用後,主從節點的切換是自動化的,客戶端由原來的連接主節點到現在的客戶端連接哨兵節點,主從切換時客戶端幾乎不會感知.
哨兵(sentinel)的作用集中在下列幾個方向
redis哨兵是一個分布式的系統,意味著多個哨兵節點協同工作,帶來的優勢如下所述.
哨兵的版本分為版本1和版本2,版本1在redis2.6正式發布,但是是不穩定版本,已經遺棄,從redis2.8開始,哨兵版本2正式推出.
哨兵服務支持以下兩種方式啟動,哨兵默認監聽tcp的26379埠.
redis-sentinel /path/to/sentinel.confredis-server /path/to/sentinel.conf --sentinel
在部署哨兵前,我們需要知道下列基礎知識
在哨兵的主配置文件sentinel.conf中,基本的配置信息如下.
sentinel monitor mymaster 127.0.0.1 6379 2sentinel down-after-milliseconds mymaster 60000sentinel failover-timeout mymaster 180000sentinel parallel-syncs mymaster 1sentinel monitor resque 192.168.1.3 6380 4sentinel down-after-milliseconds resque 10000sentinel failover-timeout resque 180000sentinel parallel-syncs resque 5
該參數用於指定哨兵監控一個主從複製架構中的主節點信息,其中<master-group-name>用於指定該主從複製架構在哨兵中的別名,該命名可以隨意從這裡我們也可以看出,哨兵可以同時對多個主從複製的架構進行監控,只要別名不重複即可, <ip>為主節點的ip,<port>為主節點的port,<quorum>的中文意思是法定人數,這裡代指sentinel節點,意思就是在當前這個主從複製的架構中,有多少個哨兵節點認為當前redis主節點故障才會發生故障轉移,如值為3,說明至少要有3個哨兵節點監測到主節點故障後,才會執行故障轉移操作,quorum只是為了用來認定主節點故障的最低哨兵節點數量,並不負責故障轉移,故障轉移操作是由優先級最高的哨兵節點負責.這個優先級最高的哨兵節點是經過大多數的哨兵節點授權的.當有2個哨兵節點認為主節點故障時並不會觸發故障轉移,因為沒有達到最低的quorum數量.
這裡需要注意的是,我們只需要填寫一個主從複製架構中的主節點地址埠信息即可,不需要填寫從節點的信息,因為填寫主節點後,哨兵會通過主節點的info命令獲取該主節點的所有從節點信息.那麼這裡我們可以想到一個問題,如果我們把主節點的ip地址寫到配置文件中,那麼相當於寫死了這個主ip地址,故障轉移後,哨兵將從節點升級為了主節點,主節點的ip地址也會發生變化,但是配置文件記錄的主ip地址還是故障以前的主節點的IP位址,這裡會不會有問題?實際上不會的,剛才說到,多個哨兵節點中會授權其中一個優先級最高的哨兵節點來負責故障轉移,將一個優先級最高的從節點升級為主節點,並將這個新主節點的ip地址更新到配置文件中,然後重新配置原來的從節點並讓其成為新主節點的從節點,哨兵將新的主節點信息廣播到其他哨兵節點,其他哨兵節點再更新自己的配置文件,到最後各個哨兵節點的額監控信息會最終達到一致性狀態.
該參數表示哨兵節點認為監視的主從架構中主節點的故障超時時間
該參數作用:
指定同一個哨兵節點對同一個主節點執行兩次故障轉移之間的時間.
指定當一個從節點從一個錯誤的主節點同步數據到從節點被糾正為向正確的主節點同步數據的時間.
指定取消一個正在進行的failover所需要的時間.
指定當進行故障轉移時,配置所有從節點指向新的主節點所需的最大時間.
這個配置項指定了在發生故障轉移時主備切換時最多可以有多少個從節點同時對新的主節點進行同步,這個數字越小,完成故障恢復所需的時間就越長,但是如果這個數字越大,就意味著越多的從節點因為故障轉移而不能被訪問,可以通過將這個值設為1來保證每次只有一個從節點同步新的主節點.
一個redis主節點被哨兵節點認定處於下線時有兩種不同的下線狀態,第一個階段為主觀下線(Subjectively Down)狀態,即當前的哨兵節點認為主節點下線,第二個階段是客觀下線(Objectively Down),當第一個主觀下線階段發生後,超過quorum個哨兵節點認為主節點下線,那麼當前哨兵節點就會從其他哨兵節點得到主節點「SENTINEL is-master-down-by-addr」的命令反饋,主節點就會進入客觀下線狀態.
從上一節可知,主節點被認為進入主觀下線(SDOWN)的條件是達到了參數down-after-milliseconds的指定超時時間,即在該時間內哨兵沒有收到對主節點的ping命令返回。
哨兵節點通過每秒發送ping命令到主節點,以檢測主節點是否下線.主節點的返回值包含以下三種
除此之外的其他返回值是無效的。
如我們將參數down-after-milliseconds設置為30000毫秒,即30秒,那麼在29秒的時候。哨兵收到主節點的ping返回值為+PONG,那麼我們認為主節點是正常的。
主節點被認為處於主觀下線狀態並不能觸發哨兵的故障轉移操作,它僅僅意味著主節點在當前哨兵節點看來不可達,只有到客觀下線狀態時,故障轉移操作才會發生.這裡需要注意的是,客觀下線的狀態只發生在監測主節點時,從節點並沒有客觀下線狀態這一說.而如果從節點由於故障處於主觀下線狀態後,在遇到主節點不可達時,哨兵在進行故障轉移時並不會考慮將該從節點提升為主節點
各個哨兵節點之間互相周期性通信並交互信息以檢查哨兵是否正常工作,但是我們在配置哨兵的配置文件時卻沒有指定其他哨兵的地址,這是為什麼呢?前面我們介紹過哨兵中只需要配置主節點的地址即可,實際上哨兵節點之間的互相通信使用的是redis的發布訂閱功能,通過該功能,哨兵可以知道還有其他哨兵節點也在監控主節點和從節點信息。
哨兵節點通過主節點的info命令獲取連接該主節點的其他從節點信息,並向主節點和從節點的頻道 __sentinel__:hello發送hello消息,下列描述了哨兵節點的自動發現機制。
即使當前沒有發生故障轉移,哨兵節點仍然會試著嘗試更新被監控節點的配置。
對於哨兵節點重新配置從節點而言,錯誤的配置在一定的時間內必須被發現,該時間一定大於廣播新配置的周期,這阻止了剛從網絡故障中恢復並且包含過期信息的哨兵節在接收到更新之前嘗試修改從節點配置信息,因為剛從網絡故障中恢復的哨兵可能包含老的主節點數據,其他哨兵節點必須保證該剛恢復的哨兵擁有最新的配置數據才能參加到新的監控環境中繼續工作。
哨兵節點也會採取更加穩健的措施來保證儘可能的將網絡故障的影響降到最低。
雖然多個哨兵節點功能監控redis主從架構的運行,但是實際執行故障轉移時只能由一個領頭哨兵節點來完成,該領頭哨兵節點必須得到大多數哨兵節點的授權,所以需要選舉除一個優先級最高的領頭節點,該選舉過程只用了Raft算法。
當一個哨兵節點準備做故障轉移時,會挑選一個優先級最高的從節點升級為主節點,挑選一個優先級最高的從節點遵從以下原則。
哨兵節點執行故障轉移時需要得到大部分哨兵節點的授權,這是因為當一個領頭哨兵被授權時,它會獲得一個唯一的配置紀元用來為主節點執行故障轉移,這個配置紀元用來在故障轉移後標註新的配置的版本,例如新的配置版本中主節點的ip地址發生了改變,因為大多數哨兵節點同意一個給定的配置紀元分配給一個指定的領頭哨兵,沒有其他哨兵會使用這個配置紀元,這就意味著每一次故障轉移都會有一個新的配置版本和新的配置紀元相匹配。
除此之外哨兵節點還有一個遵守的規則,如果一個哨兵節點由於主節點需要故障轉移而投票給另外一個哨兵節點同意選舉為領頭節點,等待一段時間後,領頭節點依然會對同一個主節點執行故障轉移,該時間通過failover-timeout參數指定,這也限制了同一時間只有一個哨兵節點可以執行故障轉移。
一旦領頭哨兵節點執行完故障轉移後,便會廣播新的配置信息,這樣其他哨兵節點收到信息後及時更細自己的配置信息。如何判斷一個故障轉移操作是否完成呢,它需要哨兵節點能夠在優先級最高的從節點成功轉型REPLICAOF NO ONE命令,該命令會將從節點升級為主節點,稍後聽過info命令便可以觀察到角色已經切換為master。
此時,即使哨兵節點正在重新配置從節點的新主節,故障轉移也會被認為是成功的,所有的哨兵節點都會被領頭哨兵節點要求更新配置信息,這也是之前介紹的領頭哨兵會被分配一個配置紀元。
每一個哨兵節點通過redis的發布訂閱功能在主節點和從節點不間斷的廣播關於主節點的配置版本,與此同時,所以的哨兵節點也會觀察其他哨兵節點廣播的配置信息。
這裡廣播的發生在我們前面介紹的__sentinel__:hello頻道。
因為每一個哨兵廣播的配置都可能有不同的版本號,版本號最大的總是可以贏得版本號較小的,如在故障轉移之前,哨兵節點A廣播主節點的地址是192.168.1.50:6379,配置版本號是1,哨兵節點A負責故障轉移操作並成功後,配置版本號變成了2,那麼哨兵A在廣播時指定新的主節點的地址是192.168.1.60:6379,配置版本號是2,其他哨兵節點看到哨兵A的配置版本號比自己的高,會立刻更新自己的配置數據,這也說明了在一個周期結束後,所有的哨兵節點都會根據最高的版本號更新自己的配置信息並最終達到一致性。