Redis Sentinel

 這節介紹Redis的高可用解決方案:Sentinelhtml

1.介紹

 Sentinel是Redis官方推薦的高可用(HA)解決方案,當用Redis作master-slave的高可用方案時,假如master宕機了,Redis自己(包括它的不少客戶端)都沒有實現自動進行主備切換。redis

 Sentinel自己是一個運行在特殊模式下的Redis服務器,它能監控多個master-slave集羣,發現master宕機後能進行自動切換。服務器

2.獲取信息方式

 sentinel經過配置項中的網絡

sentinel monitor  <master name>  <master ip>  <master port>  <quorum>

選項來獲取master節點的信息。3d

 在啓動後sentinel會創建同master節點的命令鏈接和訂閱鏈接。以便經過命令鏈接向主節點發送命令,經過訂閱鏈接訂閱服務器的 sentinel:hello 頻道。code

file

 sentinel每10秒會向master節點發送INFO命令,經過分析命令的返回結果可以知道主節點和從節點的信息。對於每一個從節點,sentinel也會向它創建一個命令鏈接和訂閱鏈接。htm

 sentinel每2秒經過命令鏈接向所監聽的節點發送訂閱命令,如blog

PUBLISH _sentinel_:hello …..

其中的信息包括了sentinel自己的信息以及本身記錄的主節點信息。同時,sentinel也會訂閱_sentinel_:hello頻道,因此sentinel可以以這種方式同其餘的sentinel節點通訊,以同步信息,見goosip協議排序

 當sentinel從訂閱信息中發現一個新的sentinel節點時,會向該新發現的節點創建命令鏈接,最後監視同一主服務器的各個sentinel節點會造成互相鏈接的網絡。ip

file

3.節點失效

 配置項

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判斷主節點處於客觀下線狀態後,會觸發故障轉移。

4.故障轉移

 發生故障轉移時,會從監聽主節點的sentinel中選舉出主的sentinel來處理故障轉移的過程。選舉的過程相似於Raft協議,由標記客觀下線的sentinel節點充當candidate,向其餘sentinel節點(follower)發起投票,當某個candidate從follower得到的票數超過一半後,該候選者就會成爲leader。而sentinel中的epoch,配置紀元相似於Raft中的term,每次選舉後都會自增。主要過程爲:

  1. 每一個充當candidate的sentinel節點都會要求其餘sentinel節點發送is-master-down-addr命令,將本身設置爲leader。

  2. 收到命令的sentinel節點,若是當前epoch和candidate傳給他的epoch同樣,說明他已經把本身的票投給了其餘candidate。投過票給別的sentinel後,在當前epoch內本身就只能成爲follower。若是該節點還沒投過票,會採起先到先得的規則,將本身的票投給請求的candidate節點。

  3. 收到回覆的candidate節點,會檢查響應的epoch值和leader_runid值是否同自身的值一致,是的話則表示得到了一票。

  4. 當某個candidate節點得到半數以上的票數時,該節點便成爲了leader節點。

  5. 若是必定時間內無法選舉出leader節點,則每一個candidate節點會等待隨機時間後再次發起選舉,知道選出leader節點爲止。

 選舉出領頭sentinel節點後,將由該節點處理故障轉移,過程以下:

  1. 在已下線主節點的全部從節點中,選出一個從節點,將其轉換爲主節點。

     主sentinel會按照下面的規則選擇適合的slave節點上升爲master節點:

    1. 去除已下線的slave節點

    2. 去除最近五秒內沒有回覆過主sentinel節點INFO信息的slave節點

    3. 去除與已下線主節點鏈接斷開超過down-after-milliseconds*10毫秒的slave節點

    4. 根據各slave節點的優先級,從小到大排序,選擇優先級最小的節點。對於相同優先級的節點,選擇複製偏移量最大和runid最小的節點。

     最後向被選擇出來的slave節點發送SLAVE OF NO ONE命令。

  2. 向已下線主節點下的全部從節點發送SLAVE OF命令,改成複製新的主節點。

  3. 將已下線主節點設置爲新主節點的從節點。

 其中,上面步驟1)中的slave節點優先級由redis配置文件中的slave-priority N 選項控制。0做爲一個特殊的優先級,標識這個slave不能做爲master,因此一個優先級爲0的slave永遠不會被 哨兵挑選提高爲master。

 上步驟2) 中,從節點須要同步新的主節點的信息,期間會致使從節點不可用,能夠經過

sentinel parallel-syncs mymaster <n>

來控制同時進行同步的從節點的數量。這個數字越小,完成故障轉移所需的時間就越長,可是若是這個數字越大,就意味着越多的slave由於複製而不可用。

5.腦裂時的數據一致性

 Redis不保證強一致性,在發生網絡故障時,有可能出現腦裂。從腦裂發生到網絡恢復正常,複製結束的這段時間裏,異常主節點寫入的數據將丟失。爲了不數據的丟失,能夠對主節點增長以下配置:

min-slaves-to-write 1	#執行寫操做所需的最少slave服務器數量,若是數量少於設定的值,寫操做將被拒絕
	
	min-slaves-max-lag 10	#網絡延遲的最大時間,當寫操做延遲大於所設定的時間,寫操做將被拒絕

file

我的公衆號:啊駝

相關文章
相關標籤/搜索