消失了一段時間,我又回來啦。不多說,繼續把哨兵看完。 檢測主觀下線狀態 預設情況下,Sentinel會以每秒一次的頻率向所有與他創建了命令連接的實例(主從伺服器以及其他Sentinel)發送PING命令,並通過實例返回的PING命令回覆來判斷實例是否線上。 實例對PING命令的回覆可以分為兩種情況: ...
消失了一段時間,我又回來啦。不多說,繼續把哨兵看完。
檢測主觀下線狀態
預設情況下,Sentinel會以每秒一次的頻率向所有與他創建了命令連接的實例(主從伺服器以及其他Sentinel)發送PING命令,並通過實例返回的PING命令回覆來判斷實例是否線上。
實例對PING命令的回覆可以分為兩種情況:
有效回覆:實例返回+PONG、-LOADING、-MASTERDOWN三種回覆的其中一種。
無效回覆:實例返回除+PONG、-LOADING、-MASTERDOWN三種回覆之外的回覆或者規定時間內沒有收到任何回覆。
指定Sentinel判斷實例進入主觀回覆的時間長度是由Sentinel配置文件中的down-after-milliseconds選項指定的。
如果沒有收到master伺服器的回覆,Sentinel就會將master標記為主觀下線,併在master所對應的實例結構的flags屬性中打開SRI_S_DOWN標識。
檢查客觀下線狀態
當Sentinel將一個主伺服器判斷為主觀下線之後,為了確認這個主伺服器是否真的已經下線,它會向同樣監視這一主伺服器的其他Sentinel進行詢問,看他們是否也認為主伺服器已經進入下線狀態,當Sentinel從其他Sentinel那裡接收到足夠數量的已下線判斷後,Sentinel就會將主伺服器判定為科幻下線,並對主伺服器執行故障轉移操作。
使用 SENTINEL is-master-down-by-addr < ip >< port >< current_epoch >< runid >
當目標Sentinel收到源Sentinel發來的SENTINEL命令後,解析命令中的參數並根據主伺服器的ip埠號檢查主伺服器是否下線,然後回覆源Sentinel ,< down_state >< leader_runid >< leader_epoch >
根據其他Sentinel發回的SENTINEL命令回覆,統計其他SENTINEL同一主伺服器已下線的數量,當這一數量達到配置指定的判斷客觀下線所需要的數量時,Sentinel會將主伺服器實例結構flags屬性的SRI_O_DOWN標識打開,標識主伺服器已經進入客觀下線狀態。
選舉頭領Sentinel
當一個主伺服器被判斷為客觀下線時,監聽這個下線主伺服器的各個Sentinel會進行協商,選舉出一個頭領Sentinel,並由頭領Sentinel對下線主伺服器執行故障轉移操作。
1、所有線上的Sentinel都會有被選為頭領Sentinel的資格,換句話說,監視同一個主伺服器的多個線上Sentinel中的任何一個都有成為領頭Sentinel。
2、每次進行頭領Sentinel選舉之後,不論選舉是否成功,所有Sentinel的配置紀元的值都會自增一次,配置紀元實際上就是一個計數器。
3、在一個配置紀元所有Sentinel都有一次將某個Sentinel設置為局部頭領Sentinel的機會,並且局部領頭一旦設置,在這個配置紀元中就不能再次更改。
4、每個發現主伺服器進入客觀下線的Sentinel都會要求其他Sentinel將自己設置為局部頭領Sentinel。
5、當源Sentinel向目標Seninel發送SENTINEL is-master-down-by-addr命令,並且命令中runid不是*而是源Sentinel的運行ID時,這表示源Sentinel要求目標Sentinel將自己設置為局部頭領Sentinel。
6、Sentinel設置局部頭領Sentinel的規則是先到先得。
7、目標Sentinel在接收到SENTINEL is-master-down-by-addr命令之後,將向源Sentinel返回一條命令回覆,回覆中的leader_runid參數和leader_epoch分別記錄了目標Sentinel的局部頭領Sentinel的運行ID和配置紀元。
8、源Sentinel在接收到目標Sentinel返回的命令之後,會檢查回覆中leader_epoch參數的值和自己的配置紀元是否相同,如果相同,那麼源Sentinel繼續取出回覆中的leader_runid參數,如果leader_runid參數的值和源Sentinel的運行ID一致,那麼標識目標Sentinel將源Sentinel設置為局部頭領Sentinel。
9、如果某個Sentinel被半數以上的Sentinel設置為局部領頭Sentinel,那麼這個Sentinel就稱為頭領Sentinel。
10、如果在給定時間限制內,沒有一個Sentinel被選舉為頭領Sentinel,那麼各個Sentinel將在一段時間之後再次進行選舉,直到選出頭領Sentinel。
故障轉移
在選舉出頭領Sentinel之後,頭領Sentinel將對這個下線的伺服器執行故障轉移操作。
1、在已下線主伺服器屬下的所有從伺服器裡面,挑選出一個從伺服器,並將其轉換為主伺服器。
挑選過程:
(1)刪除列表中的所有處於下線或者斷線狀態的從伺服器。
(2)刪除列表中所有最近5秒內沒有服務過頭領Sentinel的INFO命令的從伺服器。
(3)刪除與已下線主伺服器連接斷開超過down-after-milliseconds * 10 毫秒的從伺服器。
(4)按照優先順序進行排序,如果優先順序最高的有多台,則按照偏移量最大的排序,如果還有多台,則按照運行ID排序取運行ID最小的從伺服器。
2、讓已下線主伺服器屬下的所有從伺服器改為複製新的主伺服器。
發送命令SLAVEOF < 新主伺服器的IP ><新主伺服器的PORT>
3、將已下線主伺服器設置為新的主伺服器的從伺服器,當這個舊的主伺服器重新上線時,他就會成為新的主伺服器的從伺服器。
每天學一點,總會有收穫。
說明:尊重作者知識產權,文中內容參考《Redis設計與實現》,僅在此做學習與大家分享。