Redis 哨兵模式原理與實戰

1、複製

爲了解決單點問題,保證數據的安全性,Redis 提供了複製機制,用於知足故障恢復和負載均衡等需求。經過複製機制,Redis 能夠經過多個副本保證數據的安全性,從而提供高可用的基礎,Redis 的哨兵和集羣模式都是在複製基礎上實現高可用的。git

1.1 創建複製關係

想要對兩個 Redis 節點創建主從複製關係,能夠經過如下三種方式來實現:github

  • 在從節點的配置文件中配置 slaveof {masterHost} {masterPort} 選項;
  • 在從節點啓動時候加入 --slaveof {masterHost} {masterPort} 參數;
  • 直接在從節點上執行 slaveof {masterHost} {masterPort} 命令。

主從節點複製關係創建後,可使用 info replication 命令查看相關的複製狀態。須要注意的是每一個從節點只能有一個主節點,但主節點能夠同時擁有多個從節點,複製行爲是單向的,只能由主節點複製到從節點,所以從節點默認都是隻讀模式,即 slave-read-only 的值默認爲 yesredis

1.2 斷開復制關係

在啓動後,若是想要斷開復制關係,能夠經過在從節點上執行 slaveof no one 命令,此時從節點會斷開與主節點的複製關係,但並不會刪除原有的複製成功的數據,只是沒法再獲取主節點上的數據。算法

經過 slaveof 命令還能夠實現切換主節點的操做,命令以下:shell

slaveof {newMasterIp} {newMasterPort}
複製代碼

須要注意的是,當你從一個主節點切換到另一個主節點時,該從節點上的原有的數據會被徹底清除,而後再執行復制操做,從而保證該從節點上的數據和新主節點上的數據相同。安全

1.3 複製機制缺陷

複製機制最主要的缺陷在於,一旦主節點出現故障,從節點沒法自動晉升爲主節點,須要經過手動切換來實現,這樣沒法達到故障的快速轉移,所以也不能實現高可用。基於這個緣由,就產生了哨兵模式。bash

2、哨兵模式原理

哨兵模式的主要做用在於它可以自動完成故障發現和故障轉移,並通知客戶端,從而實現高可用。哨兵模式一般由一組 Sentinel 節點和一組(或多組)主從複製節點組成,架構以下:架構

2.1 架構說明

1. Sentinel 與 Redis Node

Redis Sentinel 是一個特殊的 Redis 節點。在哨兵模式建立時,須要經過配置指定 Sentinel 與 Redis Master Node 之間的關係,而後 Sentinel 會從主節點上獲取全部從節點的信息,以後 Sentinel 會定時向主節點和從節點發送 info 命令獲取其拓撲結構和狀態信息。負載均衡

2. Sentinel 與 Sentinel

基於 Redis 的發佈訂閱功能, 每一個 Sentinel 節點會向主節點的 __sentinel__:hello 頻道上發送該 Sentinel 節點對於主節點的判斷以及當前 Sentinel 節點的信息 ,同時每一個 Sentinel 節點也會訂閱該頻道, 來獲取其餘 Sentinel 節點的信息以及它們對主節點的判斷。運維

3. 心跳機制

經過以上兩步全部的 Sentinel 節點以及它們與全部的 Redis 節點之間都已經彼此感知到,以後每一個 Sentinel 節點會向主節點、從節點、以及其他 Sentinel 節點定時發送 ping 命令做爲心跳檢測, 來確認這些節點是否可達。

2.2 故障轉移原理

每一個 Sentinel 都會定時進行心跳檢查,當發現主節點出現心跳檢測超時的狀況時,此時認爲該主節點已經不可用,這種斷定稱爲主觀下線。以後該 Sentinel 節點會經過 sentinel ismaster-down-by-addr 命令向其餘 Sentinel 節點詢問對主節點的判斷, 當 quorum 個 Sentinel 節點都認爲該節點故障時,則執行客觀下線,即認爲該節點已經不可用。這也同時解釋了爲何必須須要一組 Sentinel 節點,由於單個 Sentinel 節點很容易對故障狀態作出誤判。

這裏 quorum 的值是咱們在哨兵模式搭建時指定的,後文會有說明,一般爲 Sentinel節點總數/2+1,即半數以上節點作出主觀下線判斷就能夠執行客觀下線。

由於故障轉移的工做只須要一個 Sentinel 節點來完成,因此 Sentinel 節點之間會再作一次選舉工做, 基於 Raft 算法選出一個 Sentinel 領導者來進行故障轉移的工做。 被選舉出的 Sentinel 領導者進行故障轉移的具體步驟以下:

  1. 在從節點列表中選出一個節點做爲新的主節點,選擇方法以下:
    • 過濾不健康或者不知足要求的節點;
    • 選擇 slave-priority(優先級)最高的從節點, 若是存在則返回, 不存在則繼續;
    • 選擇複製偏移量最大的從節點 , 若是存在則返回, 不存在則繼續;
    • 選擇 runid 最小的從節點。
  2. Sentinel 領導者節點會對選出來的從節點執行 slaveof no one 命令讓其成爲主節點。
  3. Sentinel 領導者節點會向剩餘的從節點發送命令,讓他們重新的主節點上覆制數據。
  4. Sentinel 領導者會將原來的主節點更新爲從節點, 並對其進行監控, 當其恢復後命令它去複製新的主節點。

3、哨兵模式搭建

下面演示在單機上搭建哨兵模式,多機搭建步驟亦同。須要注意的是在實際生產環境中,爲了保證高可用,Sentinel 節點須要儘可能部署在不一樣主機上,同時爲了保證正常選舉,至少須要 3個 Sentinel 節點。

3.1 配置複製集

拷貝三份 redis.conf,分別命名爲 redis-6379.conf ,redis-6380.conf ,redis-6381.conf ,須要修改的配置項以下:

# redis-6379.conf
port 6379
daemonize yes   #以守護進程的方式啓動
pidfile /var/run/redis_6379.pid  #當Redis以守護進程方式運行時,Redis會把pid寫入該文件
logfile 6379.log
dbfilename dump-6379.rdb
dir /home/redis/data/
 # redis-6380.conf
port 6380
daemonize yes
pidfile /var/run/redis_6380.pid
logfile 6380.log
dbfilename dump-6380.rdb
dir /home/redis/data/
slaveof 127.0.0.1 6379
 # redis-6381.conf
port 6381
daemonize yes
pidfile /var/run/redis_6381.pid
logfile 6381.log
dbfilename dump-6381.rdb
dir /home/redis/data/
slaveof 127.0.0.1 6379
複製代碼

3.2 配置Sentinel

拷貝三份 sentinel.conf ,分別命名爲 sentinel-26379.conf ,sentinel-26380.conf ,sentinel-26381.conf ,配置以下:

# sentinel-26379.conf
port 26379
daemonize yes
logfile 26379.log
dir /home/redis/data/
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
 # sentinel-26380.conf 
port 26380
daemonize yes
logfile 26380.log
dir /home/redis/data/
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
 # sentinel-26381.conf 
port 26381
daemonize yes
logfile 26381.log
dir /home/redis/data/
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
複製代碼

3.3 啓動集羣

分別啓動三個 Redis 節點,命令以下:

redis-server redis-6379.conf
redis-server redis-6380.conf
redis-server redis-6381.conf
複製代碼

分別啓動三個Sentinel節點,命令以下:

redis-sentinel sentinel-26379.conf
redis-sentinel sentinel-26380.conf
redis-sentinel sentinel-26381.conf
複製代碼

使用 ps -ef | grep redis 命令查看進程,此時輸出應該以下:

可使用 info replication 命令查看 Redis 複製集的狀態,此時輸出以下。能夠看到 6379 節點爲 master 節點,而且有兩個從節點,分別爲 slave0 和 slave1,對應的端口爲 6380 和 6381:

可使用 info Sentinel 命令查看任意 Sentinel 節點的狀態,從最後一句輸出能夠看到 Sentinel 節點已經感知到 6379 的 master 節點,而且也知道它有兩個 slaves 節點;同時 Sentinel 節點彼此之間也感知到,共有 3 個 Sentinel 節點:

參考資料

  1. 付磊,張益軍 . 《Redis 開發與運維》. 機械工業出版社 . 2017-3-1
  2. 官方文檔:Redis Sentinel Documentation

更多文章,歡迎訪問 [全棧工程師手冊] ,GitHub 地址:github.com/heibaiying/…

相關文章
相關標籤/搜索