這節介紹Redis的高可用解決方案:Sentinelhtml
Sentinel是Redis官方推薦的高可用(HA)解決方案,當用Redis作master-slave的高可用方案時,假如master宕機了,Redis自己(包括它的不少客戶端)都沒有實現自動進行主備切換。redis
Sentinel自己是一個運行在特殊模式下的Redis服務器,它能監控多個master-slave集羣,發現master宕機後能進行自動切換。服務器
sentinel經過配置項中的網絡
sentinel monitor <master name> <master ip> <master port> <quorum>
選項來獲取master節點的信息。3d
在啓動後sentinel會創建同master節點的命令鏈接和訂閱鏈接。以便經過命令鏈接向主節點發送命令,經過訂閱鏈接訂閱服務器的 sentinel:hello 頻道。code
sentinel每10秒會向master節點發送INFO命令,經過分析命令的返回結果可以知道主節點和從節點的信息。對於每一個從節點,sentinel也會向它創建一個命令鏈接和訂閱鏈接。htm
sentinel每2秒經過命令鏈接向所監聽的節點發送訂閱命令,如blog
PUBLISH _sentinel_:hello …..
其中的信息包括了sentinel自己的信息以及本身記錄的主節點信息。同時,sentinel也會訂閱_sentinel_:hello頻道,因此sentinel可以以這種方式同其餘的sentinel節點通訊,以同步信息,見goosip協議。排序
當sentinel從訂閱信息中發現一個新的sentinel節點時,會向該新發現的節點創建命令鏈接,最後監視同一主服務器的各個sentinel節點會造成互相鏈接的網絡。ip
配置項
sentinel down-after-milliseconds <主節點名> <中斷時間ms>
設置了sentinel主觀下線的時間。sentinel每隔一秒就會向主節點發送PING命令,若是master在「中斷時間」內不迴應PONG 或者是回覆了一個錯誤消息,那麼這個sentinel會主觀地(單方面地)認爲這個master已經不可用了(SDOWN)。
當sentinel判斷主節點已經處於主觀下線狀態後,會向其餘sentinel發送
is-master-down-by-add
命令,以詢問其餘sentinel的狀態,確認該主節點是否處於下線狀態(主觀下線或者客觀下線)。當回覆的下線狀態的數量達到配置項中的quorum值時,則該sentinel會將主節點標記爲客觀下線狀態(ODOWN)。
當sentinel判斷主節點處於客觀下線狀態後,會觸發故障轉移。
發生故障轉移時,會從監聽主節點的sentinel中選舉出主的sentinel來處理故障轉移的過程。選舉的過程相似於Raft協議,由標記客觀下線的sentinel節點充當candidate,向其餘sentinel節點(follower)發起投票,當某個candidate從follower得到的票數超過一半後,該候選者就會成爲leader。而sentinel中的epoch,配置紀元相似於Raft中的term,每次選舉後都會自增。主要過程爲:
每一個充當candidate的sentinel節點都會要求其餘sentinel節點發送is-master-down-addr
命令,將本身設置爲leader。
收到命令的sentinel節點,若是當前epoch和candidate傳給他的epoch同樣,說明他已經把本身的票投給了其餘candidate。投過票給別的sentinel後,在當前epoch內本身就只能成爲follower。若是該節點還沒投過票,會採起先到先得的規則,將本身的票投給請求的candidate節點。
收到回覆的candidate節點,會檢查響應的epoch值和leader_runid值是否同自身的值一致,是的話則表示得到了一票。
當某個candidate節點得到半數以上的票數時,該節點便成爲了leader節點。
若是必定時間內無法選舉出leader節點,則每一個candidate節點會等待隨機時間後再次發起選舉,知道選出leader節點爲止。
選舉出領頭sentinel節點後,將由該節點處理故障轉移,過程以下:
在已下線主節點的全部從節點中,選出一個從節點,將其轉換爲主節點。
主sentinel會按照下面的規則選擇適合的slave節點上升爲master節點:
去除已下線的slave節點
去除最近五秒內沒有回覆過主sentinel節點INFO信息的slave節點
去除與已下線主節點鏈接斷開超過down-after-milliseconds*10毫秒的slave節點
根據各slave節點的優先級,從小到大排序,選擇優先級最小的節點。對於相同優先級的節點,選擇複製偏移量最大和runid最小的節點。
最後向被選擇出來的slave節點發送SLAVE OF NO ONE
命令。
向已下線主節點下的全部從節點發送SLAVE OF命令,改成複製新的主節點。
將已下線主節點設置爲新主節點的從節點。
其中,上面步驟1)中的slave節點優先級由redis配置文件中的slave-priority N
選項控制。0做爲一個特殊的優先級,標識這個slave不能做爲master,因此一個優先級爲0的slave永遠不會被 哨兵挑選提高爲master。
上步驟2) 中,從節點須要同步新的主節點的信息,期間會致使從節點不可用,能夠經過
sentinel parallel-syncs mymaster <n>
來控制同時進行同步的從節點的數量。這個數字越小,完成故障轉移所需的時間就越長,可是若是這個數字越大,就意味着越多的slave由於複製而不可用。
Redis不保證強一致性,在發生網絡故障時,有可能出現腦裂。從腦裂發生到網絡恢復正常,複製結束的這段時間裏,異常主節點寫入的數據將丟失。爲了不數據的丟失,能夠對主節點增長以下配置:
min-slaves-to-write 1 #執行寫操做所需的最少slave服務器數量,若是數量少於設定的值,寫操做將被拒絕 min-slaves-max-lag 10 #網絡延遲的最大時間,當寫操做延遲大於所設定的時間,寫操做將被拒絕
我的公衆號:啊駝