消失了一段時間,我又回來啦。很少說,繼續把哨兵看完。服務器
檢測主觀下線狀態學習
默認狀況下,Sentinel會以每秒一次的頻率向全部與他建立了命令鏈接的實例(主從服務器以及其餘Sentinel)發送PING命令,並經過實例返回的PING命令回覆來判斷實例是否在線。設計
實例對PING命令的回覆能夠分爲兩種狀況:排序
有效回覆:實例返回+PONG、-LOADING、-MASTERDOWN三種回覆的其中一種。ip
無效回覆:實例返回除+PONG、-LOADING、-MASTERDOWN三種回覆以外的回覆或者規定時間內沒有收到任何回覆。ast
指定Sentinel判斷實例進入主觀回覆的時間長度是由Sentinel配置文件中的down-after-milliseconds選項指定的。配置
若是沒有收到master服務器的回覆,Sentinel就會將master標記爲主觀下線,並在master所對應的實例結構的flags屬性中打開SRI_S_DOWN標識。im
檢查客觀下線狀態統計
當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對下線主服務器執行故障轉移操做。
一、全部在線的Sentinel都會有被選爲頭領Sentinel的資格,換句話說,監視同一個主服務器的多個在線Sentinel中的任何一個都有成爲領頭Sentinel。
二、每次進行頭領Sentinel選舉以後,不論選舉是否成功,全部Sentinel的配置紀元的值都會自增一次,配置紀元實際上就是一個計數器。
三、在一個配置紀元全部Sentinel都有一次將某個Sentinel設置爲局部頭領Sentinel的機會,而且局部領頭一旦設置,在這個配置紀元中就不能再次更改。
四、每一個發現主服務器進入客觀下線的Sentinel都會要求其餘Sentinel將本身設置爲局部頭領Sentinel。
五、當源Sentinel向目標Seninel發送SENTINEL is-master-down-by-addr命令,而且命令中runid不是*而是源Sentinel的運行ID時,這表示源Sentinel要求目標Sentinel將本身設置爲局部頭領Sentinel。
六、Sentinel設置局部頭領Sentinel的規則是先到先得。
七、目標Sentinel在接收到SENTINEL is-master-down-by-addr命令以後,將向源Sentinel返回一條命令回覆,回覆中的leader_runid參數和leader_epoch分別記錄了目標Sentinel的局部頭領Sentinel的運行ID和配置紀元。
八、源Sentinel在接收到目標Sentinel返回的命令以後,會檢查回覆中leader_epoch參數的值和本身的配置紀元是否相同,若是相同,那麼源Sentinel繼續取出回覆中的leader_runid參數,若是leader_runid參數的值和源Sentinel的運行ID一致,那麼標識目標Sentinel將源Sentinel設置爲局部頭領Sentinel。
九、若是某個Sentinel被半數以上的Sentinel設置爲局部領頭Sentinel,那麼這個Sentinel就稱爲頭領Sentinel。
十、若是在給定時間限制內,沒有一個Sentinel被選舉爲頭領Sentinel,那麼各個Sentinel將在一段時間以後再次進行選舉,直到選出頭領Sentinel。
故障轉移
在選舉出頭領Sentinel以後,頭領Sentinel將對這個下線的服務器執行故障轉移操做。
一、在已下線主服務器屬下的全部從服務器裏面,挑選出一個從服務器,並將其轉換爲主服務器。
挑選過程:
(1)刪除列表中的全部處於下線或者斷線狀態的從服務器。
(2)刪除列表中全部最近5秒內沒有服務過頭領Sentinel的INFO命令的從服務器。
(3)刪除與已下線主服務器鏈接斷開超過down-after-milliseconds * 10 毫秒的從服務器。
(4)按照優先級進行排序,若是優先級最高的有多臺,則按照偏移量最大的排序,若是還有多臺,則按照運行ID排序取運行ID最小的從服務器。
二、讓已下線主服務器屬下的全部從服務器改成複製新的主服務器。
發送命令SLAVEOF < 新主服務器的IP ><新主服務器的PORT>
三、將已下線主服務器設置爲新的主服務器的從服務器,當這個舊的主服務器從新上線時,他就會成爲新的主服務器的從服務器。
天天學一點,總會有收穫。
說明:尊重做者知識產權,文中內容參考《Redis設計與實現》,僅在此作學習與你們分享。