天天看點

Redis高可用故障轉移 Redis Sentinel 哨兵模式 從配置到編碼一氣呵成

作者:添甄
滿懷憂思,不如先幹再說!

主從複制出現的問題

上篇文章《Redis主從複制》中我們說到可以對Redis單節點資料進行備份實作Redis高可用,但是如果master節點當機并不會自動做故障切換等,導緻項目中更可能需要接入多資料源,編寫代碼實作故障切換非常麻煩,Redis考慮到這個問題提供了哨兵模式,也就是Redis Sentinel!

Redis Sentinel基本架構

看圖我們說一下Redis Sentinel架構,首先我們需要加入Sentinel節點,Sentinel節點去監控Redis中Master和Slave的運作狀态,判斷是否可用,當然Sentinel節點也是有多個的,實作Sentinel節點的高可用和多節點判斷Redis節點是否可用不會出現誤判情況

用戶端不再直接操作Redis的Master或者Slave節點,而是去通路Sentinel節點!是以我們的用戶端會記錄Redis Sentinel的位址!我們的用戶端不關心誰是Master而是Sentinel告訴用戶端誰是Master,背景Master切換了,用戶端也不會受到影響!

當多個sentinel發現并确認master出現問題,會選舉出一個sentinel作為上司,選舉出一個slave為新的master,通知其餘的slave有新的master産生,通知用戶端master發生變化,等待老的master複活成為新的master的slave!

一套sentinel可以同時監控多套master和slave!節省資源!每套master/slave會有一個master-name作為辨別以示差別

Redis高可用故障轉移 Redis Sentinel 哨兵模式 從配置到編碼一氣呵成

安裝和配置

叢集規劃

  1. 配置開啟主從節點,一個master端口号為7000,兩個slave節點分别問7001和7002;
  2. 配置開啟sentinel監控主節點。(sentinel是特殊的redis節點,不存儲資料),三個sentinel分别為26379,26380,26381;
Redis高可用故障轉移 Redis Sentinel 哨兵模式 從配置到編碼一氣呵成
Redis高可用故障轉移 Redis Sentinel 哨兵模式 從配置到編碼一氣呵成

配置描述

master

port 7000
daemonize yes
pidfile /var/run/redis/redis-7000.pid
logfile "7000.log"
dir "/usr/local/redis-5.0.5/data/"           

slave-7001

指令:sed "s/7000/7001/g" redis-7000.conf > redis-7001.conf           

将7000替換為7001

指令:echo "slaveof stt101 7000" >> redis-7001.conf           

重定向slaveof stt101 7000到redis-7001.conf檔案末尾

port 7001
daemonize yes
pidfile /var/run/redis/redis-7001.pid
logfile "7001.log"
dir "/usr/local/redis-5.0.5/data/"
slaveof stt101 7000           

slave-7002

port 7002
daemonize yes
pidfile /var/run/redis/redis-7002.pid
logfile "7002.log"
dir "/usr/local/redis-5.0.5/data/"
slaveof stt101 7000           

配置完之後啟動三個節點檢視主從關系:

redis-cli -p 7000 info replication           

sentinel主要配置

#三台sentinel使用端口差別
port ${port}
dir "/usr/local/redis-5.0.5/data/"
logfile "${port}.log"
#監控主節點名字為mymaster,ip,端口,2台sentinel認為master有問題就會故障轉移
sentinel monitor mymaster ip port 2
#30000毫秒ping不通認為出現問題
sentinel down-after-milliseconds mymaster 30000
#選擇了新的master之後老的slave會對新的slave進行複制,1代表每次隻有一個slave進行複制,減輕master壓力
sentinel parallel-syncs mymaster 1
#故障轉移時間
sentinel failover-timeout mymaster 180000           

注意:在redis的安裝目錄下有一個sentinel.conf檔案就是sentinel的配置檔案,我們将這個檔案拷貝到conf目錄下,去除注釋等。給出一個26739的配置,其餘的兩台大家隻需修改端口号了pid檔案即可

第一台的配置
port 26379
daemonize yes
pidfile "/var/run/redis/redis-sentinel-26379.pid"
logfile "26379.log"
dir "/usr/local/redis-5.0.5/data"
#stt101為ip映射
sentinel monitor mymaster stt101 7000 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
protected-mode no

#通過該指令将sentinel.conf檔案去掉注釋和換行将内容放到redis-sentinel-26739.conf檔案中
cat sentinel.conf | grep -v "#" | grep -v "^#34; > redis-sentinel-26739.conf
#啟動
redis-sentinel redis-sentinel-26739.conf

#配置其他兩台,三台配置是一樣的,修改端口和日志檔案,pid檔案即可
sed "s/26379/26380/g" redis-sentinel-26379.conf > redis-sentinel-26380.conf
sed "s/26379/26381/g" redis-sentinel-26379.conf > redis-sentinel-26381.conf           

啟動

# 使用redis-sentinel指令讀取配置檔案分别啟動三台sentinel節點
# 記得修改檔案名哦
redis-sentinel redis-sentinel-26739.conf

# 分别啟動三台Redis節點
redis-server redis-6379.conf

# 通過用戶端連接配接上sentinel節點
redis-cli -h 192.168.109.101 -p 26379

           
這裡大家注意一下:有些可能有疑問,上邊端口不是7000嗎下邊咋變成6379了,搞咩啊,之前在寫的時候,這裡有一點小瑕疵,我直接重寫了,端口号上下沒有對應起來,這裡聲明一下,之前的7000,7001,7002分别對應下文的6379,6380,6381,如果沒有發現問題,是不沒認真看啊!

啟動之後檢視狀态

大家看下邊動圖,名字為6379, 6380, 6381的為redis節點,名字為26379的為sentinel節點,示範節點狀态和故障轉移

Redis高可用故障轉移 Redis Sentinel 哨兵模式 從配置到編碼一氣呵成
  • 首先在redis sentinel下檢視address是6381,說明其為主節點
  • 之後将6381kill掉,等待一段時間,這裡時間大概在30S左右,這段時間我暫停了
  • 之後再檢視info資訊,發現address變為6380

SpringBoot內建Redis Sentinel示範

這個思路也很簡單,我們循環添加或者查詢資料,将主節點手動當機,檢視日志列印是否成功切換繼續讀寫資料即可,我們隻需要修改application.yml配置檔案即可

配置檔案

spring:
  redis:
    #host: 192.168.109.101  #這是之前單機時的ip配置
    #port: 6379              # 這個是單機時的端口配置,現在都不用寫了
    sentinel:
      # 寫sentinel節點的ip:port
      nodes: 192.168.109.101:26379,192.168.109.102:26380,192.168.109.103:26381
      # 寫sentinel節點的名字,因為sentinel可以有很多組,每一組使用名字區分
      master: mymaster
    timeout: 2s
      #連接配接池最大連接配接數(使用負值表示沒有限制)
    max-active: 2000
      #連接配接池最大阻塞等待時間(使用負值表示沒有限制)
    max-wait: -1ms
      #連接配接池中的最大空閑連接配接
    max-idle: 1024
      #連接配接池中的最小空閑連接配接
    min-idle: 100           

代碼

/**
添加資料
*/
@Test
public void test7(){
   //循環,添加資料
   for (int i = 0; i < 200; i++) {
     String key = "key-" + i;
	 String value = "value-" + i;
	 try {
		redisTemplate.opsForValue().set(key,value);
		//慢一點
		Thread.sleep(500);
		System.out.println("目前插入:" + key + "===>" + value);
     } catch (InterruptedException e) {
		e.printStackTrace();
	 }catch (Exception e){
		e.printStackTrace();
	 }
   }
   System.out.println("資料插入完成");
}

/**
查詢資料
*/
@Test
public void test8(){
   //編寫循環,添加資料
   for (int i = 0; i < 200; i++) {
        String key = "key-" + i;
        try {
            Object o = redisTemplate.opsForValue().get(key);
            //慢一點
            Thread.sleep(500);
            System.out.println("目前擷取:" + o );
        } catch (InterruptedException e) {
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}           

示範

這裡我又将剛剛關閉的6381節點啟動,三個節點提供服務,進行示範,一樣的動圖送給大家,這裡隻貼出插入資料的動圖了,查詢的類似,大家動手做一做試一下!

Redis高可用故障轉移 Redis Sentinel 哨兵模式 從配置到編碼一氣呵成

基本原理

由三個定時任務實作的切換

每10S一個info

每10秒每個sentinel節點會對master和slave發送一個info指令,一是為了發現slave節點,二是為了确認主從關系

Redis高可用故障轉移 Redis Sentinel 哨兵模式 從配置到編碼一氣呵成

每2秒交換資訊

每2秒每個sentinel通過master節點的channel交換資訊(pub/sub),相當于一個sentinel的互動平台,互動對master/slave狀态的監聽情況和自身的資訊。通過一個名為__sentinel__:hello的頻道互動,每個sentinel節點都會訂閱這個頻道

Redis高可用故障轉移 Redis Sentinel 哨兵模式 從配置到編碼一氣呵成

每秒1ping

每一秒每個sentinel節點對其他sentinel和redis執行一次ping,這一步基于第一步sentinel掌握redis的master和slave節點的狀況,基于第二步sentinel節點知道其他的sentinel節點,對他們進行心跳檢測,判斷是否在正常工作

收藏等于學會!别忘了點贊,關注哦,高頻推出技術文章,有問題記得評論或者私信!

繼續閱讀