1. 程式人生 > >Redis 學習筆記(十三)Redis Sentinel 介紹與部署

Redis 學習筆記(十三)Redis Sentinel 介紹與部署

Redis Sentinel 介紹與部署

1. Sentinel介紹

1.1 主從複製的問題

Redis主從複製可將主節點資料同步給從節點,從節點此時有兩個作用:

  • 一旦主節點宕機,從節點作為主節點的備份可以隨時頂上來。
  • 擴充套件主節點的讀能力,分擔主節點讀壓力。

但是問題來了:

  • 一旦主節點宕機,從節點晉升成主節點,同時需要修改應用方的主節點地址,還需要命令所有從節點去複製新的主節點,整個過程需要人工干預。
  • 主節點的寫能力受到單機的限制。
  • 主節點的儲存能力受到單機的限制。

第一個問題,我們接下來講的Sentinel就可以解決。而後兩個問題,Redis也給出了方案Redis Cluster

1.2 Redis Sentinel的高可用

Redis Sentinel是一個分散式架構,包含若干個Sentinel節點和Redis資料節點,每個Sentinel節點會對資料節點和其餘Sentinel節點進行監控,當發現節點不可達時,會對節點做下線標識。

如果被標識的是主節點,他還會選擇和其他Sentinel節點進行“協商”,當大多數的Sentinel節點都認為主節點不可達時,他們會選舉出一個Sentinel節點來完成自動故障轉移工作,同時將這個變化通知給Redis應用方。

整個過程完全自動,不需要人工介入,所以可以很好解決Redis的高可用問題。

接下來我們就通過部署一個Redis Sentinel

例項來了解整體框架。

2. Redis Sentinel部署

我們部署的拓撲結構如圖所示:

這裡寫圖片描述

分別有3個Sentinel節點,1個主節點,2個從節點組成一個Redis Sentinel

role IP port
master 127.0.0.1 6379
slave1 127.0.0.1 6380
slave2 127.0.0.1 6381
Sentinel1 127.0.0.1 26379
Sentinel2 127.0.0.1 26380
Sentinel3 127.0.0.1 26381

2.1 啟動主節點

  • 配置:
port 6379
daemonize yes
logfile "6379.log"
dbfilename "dump-6379.rdb"
dir "/var/redis/data/"
  • 啟動主節點
➜   sudo redis-server redis-6379.conf
  • 使用PING命令檢測是否啟動
➜   redis-cli -h 127.0.0.1 -p 6379 ping
PONG

2.2 啟動兩個從節點

  • 配置(兩個從節點配置相同,除了檔名有區分)
port 6380
daemonize yes
logfile "6380.log"
dbfilename "dump-6380.rdb"
dir "/var/redis/data/" 
slaveof 127.0.0.1 6379      // 從屬主節點
  • 啟動兩個從節點
➜   sudo redis-server redis-6380.conf 
➜   sudo redis-server redis-6381.conf 
  • 使用PING命令檢測是否啟動
➜   redis-cli -h 127.0.0.1 -p 6380 ping
PONG
➜   redis-cli -h 127.0.0.1 -p 6381 ping
PONG

2.3 確認主從關係

  • 主節點視角
➜   redis-cli -h 127.0.0.1 -p 6379 INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=85,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=85,lag=0
......
  • 從節點視角(6380埠)
➜   redis-cli -h 127.0.0.1 -p 6380 INFO replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
......

確立中從關係,如下圖所示:

這裡寫圖片描述

2.4 部署Sentinel節點

3個Sentinel節點的部署方法是相同的(埠不同)。以26379為例。

  • 配置
// Sentinel節點的埠
port 26379  
dir /var/redis/data/
logfile "26379.log"

// 當前Sentinel節點監控 127.0.0.1:6379 這個主節點
// 2代表判斷主節點失敗至少需要2個Sentinel節點節點同意
// mymaster是主節點的別名
sentinel monitor mymaster 127.0.0.1 6379 2

//每個Sentinel節點都要定期PING命令來判斷Redis資料節點和其餘Sentinel節點是否可達,如果超過30000毫秒且沒有回覆,則判定不可達
sentinel down-after-milliseconds mymaster 30000

//當Sentinel節點集合對主節點故障判定達成一致時,Sentinel領導者節點會做故障轉移操作,選出新的主節點,原來的從節點會向新的主節點發起復制操作,限制每次向新的主節點發起復制操作的從節點個數為1
sentinel parallel-syncs mymaster 1

//故障轉移超時時間為180000毫秒
sentinel failover-timeout mymaster 180000
  • 啟動(兩種方法)
    • redis-sentinel sentinel-26379.conf
    • redis-server sentinel-26379.conf --sentinel
sudo redis-sentinel sentinel-26379.conf --sentinel
  • 確認
➜   redis-cli -h 127.0.0.1 -p 26379 INFO Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=1 //sentinels=1表示啟動了1個Sentinel

部署三個Sentinel節點之後,真個拓撲結構如圖所示:

這裡寫圖片描述

  • 當部署號Redis Sentinel之後,會有如下變化
    • Sentinel節點自動發現了從節點、其餘Sentinel節點。
    • 去掉了預設配置,例如:parallel-syncsfailover-timeout
    • 新添加了紀元(epoch)引數。

我們拿埠26379的舉例,啟動所有的Sentinel和資料節點後,配置檔案如下:

port 26379
dir "/var/redis/data"
sentinel myid 70a3e215c1a34b4d9925d170d9606e615a8874f2
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
daemonize yes
logfile "26379.log"
// 發現了兩個從節點
sentinel known-slave mymaster 127.0.0.1 6381
sentinel known-slave mymaster 127.0.0.1 6380
// 傳送了連個Sentinel節點
sentinel known-sentinel mymaster 127.0.0.1 26381 e1148ad6caf60302dd6d0dbd693cb3448e209ac2
sentinel known-sentinel mymaster 127.0.0.1 26380 39db5b040b21a52da5334dd2d798244c034b4fc3
sentinel current-epoch 0

2.5 故障轉移實驗

先檢視一下節點的程序pid

➜   ps -aux | grep redis
root     18225  0.1  0.0  40208 11212 ?        Ssl  22:10   0:05 redis-server 127.0.0.1:6379
root     18234  0.0  0.0  38160  8364 ?        Ssl  22:10   0:04 redis-server 127.0.0.1:6380
root     18244  0.0  0.0  38160  8308 ?        Ssl  22:10   0:04 redis-server 127.0.0.1:6381
root     20568  0.1  0.0  38160  8460 ?        Ssl  23:05   0:02 redis-sentinel *:26379 [sentinel]
root     20655  0.1  0.0  38160  8296 ?        Ssl  23:07   0:02 redis-sentinel *:26380 [sentinel]
root     20664  0.1  0.0  38160  8312 ?        Ssl  23:07   0:02 redis-sentinel *:26381 [sentinel]

我們幹掉埠6379的主節點。

➜   sudo kill -9 18225
➜   ps -aux | grep redis
root     18234  0.0  0.0  38160  8364 ?        Ssl  22:10   0:05 redis-server 127.0.0.1:6380
root     18244  0.0  0.0  38160  8308 ?        Ssl  22:10   0:05 redis-server 127.0.0.1:6381
root     20568  0.1  0.0  38160  8460 ?        Ssl  23:05   0:03 redis-sentinel *:26379 [sentinel]
root     20655  0.1  0.0  38160  8296 ?        Ssl  23:07   0:03 redis-sentinel *:26380 [sentinel]
root     20664  0.1  0.0  38160  8312 ?        Ssl  23:07   0:03 redis-sentinel *:26381 [sentinel]

此時,Redis Sentinel對主節點進行客觀下線(Objectively Down, 簡稱 ODOWN)的判斷,確認主節點不可達,則通知從節點中止複製主節點的操作。

這裡寫圖片描述

當主節點下線時長超過配置的下線時長30000秒,Redis Sentinel執行故障轉移操作。

此時,我們檢視一下Sentinel節點監控的主節點資訊:

127.0.0.1:26379> sentinel masters 
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "6380"           //可以看到主節點已經成為6380埠的節點
    7) "runid"
    8) "084850ab4ff6c2f2502b185c8eab5bdd25a26ce2"
    9) "flags"
   10) "master"
    ..............

看一下Sentinel節點監控的從節點資訊:

127.0.0.1:26379> sentinel slaves mymaster
1)  1) "name"
    2) "127.0.0.1:6379"             //ip:port
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "6379"
    7) "runid"
    8) ""
    9) "flags"
   10) "s_down,slave,disconnected"  //埠6379的原主節點已經斷開了連線
   ..............
2)  1) "name"
    2) "127.0.0.1:6381"             
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "6381"
    7) "runid"
    8) "24495fe180e4fd64ac47467e0b2652894406e9e4"
    9) "flags"
   10) "slave"                      //本來的從節點,還是從節點的role
    ..............

由以上資訊可得,埠為6380的Redis資料節點成為新的主節點,埠為6379的舊主節點斷開連線。如圖所示:

這裡寫圖片描述

我們在試著重啟埠6379的資料節點。

➜   sudo redis-server redis-6379.conf 
➜   ps -aux | grep redis              
root     18234  0.1  0.0  40208 11392 ?        Ssl  522   0:06 redis-server 127.0.0.1:6380
root     18244  0.1  0.0  40208 10356 ?        Ssl  522   0:07 redis-server 127.0.0.1:6381
root     20568  0.1  0.0  38160  8460 ?        Ssl  522   0:05 redis-sentinel *:26379 [sentinel]
root     20655  0.1  0.0  38160  8296 ?        Ssl  522   0:05 redis-sentinel *:26380 [sentinel]
root     20664  0.1  0.0  38160  8312 ?        Ssl  522   0:05 redis-sentinel *:26381 [sentinel]
menwen   22475  0.0  0.0  14216  5920 pts/2    S+   522   0:00 redis-cli -p 26379
// 6379的資料節點已重啟
root     22617  0.0  0.0  38160  8304 ?        Ssl  00:00   0:00 redis-server 127.0.0.1:6379   

看看發生什麼:

127.0.0.1:26379> sentinel slaves mymaster
1)  1) "name"
    2) "127.0.0.1:6379"     //6379埠的節點重啟後,變成了"活"的從節點
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "6379"
    7) "runid"
    8) "de1b5c28483cf150d9550f8e338886706e952346"
    9) "flags"
   10) "slave"
    ..............
2)  1) "name"               //6381埠的節點沒有變化,仍是從節點
    2) "127.0.0.1:6381"
    ..............

他被降級成為埠6380的從節點。

這裡寫圖片描述

從上面的邏輯架構和故障轉移試驗中,可以看出Redis Sentinel的以下幾個功能。

  • 監控Sentinel節點會定期檢測Redis資料節點和其餘Sentinel節點是否可達。
  • 通知Sentinel節點會將故障轉移通知給應用方。
  • 主節點故障轉移:實現從節點晉升為主節點並維護後續正確的主從關係。
  • 配置提供者:在Redis Sentinel結構中,客戶端在初始化的時候連線的是Sentinel節點集合,從中獲取主節點資訊。

3. Sentinel配置說明

  • sentinel monitor mymaster 127.0.0.1 6379 2

    • 當前Sentinel節點監控 127.0.0.1:6379 這個主節點
    • 2代表判斷主節點失敗至少需要2個Sentinel節點節點同意
    • mymaster是主節點的別名
  • sentinel down-after-milliseconds mymaster 30000

    • 每個Sentinel節點都要定期PING命令來判斷Redis資料節點和其餘Sentinel節點是否可達,如果超過30000毫秒且沒有回覆,則判定不可達
  • sentinel parallel-syncs mymaster 1

    • 當Sentinel節點集合對主節點故障判定達成一致時,Sentinel領導者節點會做故障轉移操作,選出新的主節點,原來的從節點會向新的主節點發起復制操作,限制每次向新的主節點發起復制操作的從節點個數為1。
  • sentinel failover-timeout mymaster 180000

    • 故障轉移超時時間為180000
  • sentinel auth-pass \ \
    • 如果Sentinel監控的主節點配置了密碼,可以通過sentinel auth-pass配置通過新增主節點的密碼,防止Sentinel節點無法對主節點進行監控。
    • 例如:sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
  • sentinel notification-script \ \
    • 在故障轉移期間,當一些警告級別的Sentinel事件發生(指重要事件,如主觀下線,客觀下線等)時,會觸發對應路徑的指令碼,想指令碼傳送相應的事件引數。
    • 例如:sentinel notification-script mymaster /var/redis/notify.sh
  • sentinel client-reconfig-script \ \
    • 在故障轉移結束後,觸發應對路徑的指令碼,並向指令碼傳送故障轉移結果的引數。
    • 例如:sentinel client-reconfig-script mymaster /var/redis/reconfig.sh