redis 哨兵模式原理和搭建


哨兵模式:
哨兵(sentinel),用於對主從結構中的每一台服務器進行監控,當主節點出現故障后通過投票機制來挑選新的主節點,並且將所有的從節點連接到新的主節點上。(可以說是主從架構的智能化 哈)
哨兵需要做的事情如下:
監控:監控主從節點運行情況。
通知:當監控節點出現故障,哨兵之間進行通訊。
自動故障轉移:當監控到主節點宕機后,斷開與宕機主節點連接的所有從節點,然后在從節點中選取一個作為主節點,將其他的從節點連接到這個最新的主節點。最后通知客戶端最新的服務器地址。
哨兵的節點最少是三台服務器,必須是單數(投票防止平票的情況)哨兵自己的通信底層都是用發布訂閱的方式,  我們程序連接都是連接哨兵就可以了;

宕機情況:

1.主觀宕機:單獨哨兵認為你宕機了,發現了故障。

2.客觀宕機:半數哨兵認為主節點宕機,發現了故障。

選舉主節點的原則:

1.健康度。。從節點響應的時間

2.完整性。根據我們從節點備份的完整性,根據數據備份偏移量

3.穩定性。根據啟動時間周期,心跳檢測

4.如果上面三個條件都相等,則根據我們節點啟動時分配的run id來,如果runid越小,則最有可能選擇為我們主節點

數據丟失的問題是指:當客戶端已經把數據寫到主節點上了 ,突然主節點掛了,但主節點的數據是還沒有同步到某個從節點,從節點就替換了主節點成為主節點 這個時候的數據不一致才叫數據丟失問題

 先用原本設置好的文件配置主從模式:

1.在服務其中創建目錄

mkdir /usr/local/etc/redis/sentinel/sentinel -p
cd /usr/local/etc/redis/sentinel/sentinel

2.把文件夾sentinel,server 拉到這個目錄下

切換到server目錄下

我們配置了三個文件 :docker-compose.yml  redis-master.conf   redis-slave1.conf  redis-slave2.conf 分別配置內容如下 

version: '3'

services:
  # 主節點的容器
  redis-server-master:
    image: redis
    container_name: redis-server-master
    restart: always
    # 為了規避Docker中端口映射可能帶來的問題
    # 這里選擇使用host網絡
    network_mode: host
    # 指定時區,保證容器內時間正確
    environment:
      TZ: "Asia/Shanghai"
    volumes:
      # 映射配置文件和數據目錄
      - ./redis-master.conf:/usr/local/etc/redis/redis.conf
      - ./data/redis-master:/data 
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
  # 從節點1的容器
  redis-server-slave-1:
    image: redis
    container_name: redis-server-slave-1
    restart: always
    network_mode: host
    depends_on:
      - redis-server-master
    environment:
      TZ: "Asia/Shanghai"
    volumes:
      - ./redis-slave1.conf:/usr/local/etc/redis/redis.conf
      - ./data/redis-slave-1:/data 
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
  # 從節點2的容器
  redis-server-slave-2:
    image: redis
    container_name: redis-server-slave-2
    restart: always
    network_mode: host
    depends_on:
      - redis-server-master
    environment:
      TZ: "Asia/Shanghai"
    volumes:
      - ./redis-slave2.conf:/usr/local/etc/redis/redis.conf
      - ./data/redis-slave-2:/data 
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
# 監聽端口
port 6379

# 啟動時不打印logo
# 這個不重要,想看logo就打開它
always-show-logo no

# 設定密碼認證
requirepass 123456

# 禁用KEYS命令
# 一方面 KEYS * 命令可以列出所有的鍵,會影響數據安全
# 另一方面 KEYS 命令會阻塞數據庫,在數據庫中存儲了大量數據時,該命令會消耗很長時間
# 期間對Redis的訪問也會被阻塞,而當鎖釋放的一瞬間,大量請求涌入Redis,會造成Redis直接崩潰
rename-command KEYS ""
# bind 127.0.0.1

 

# 監聽端口
port 6380
always-show-logo no
requirepass 123456

rename-command KEYS ""
slaveof 127.0.0.1 6379

# 設定連接主節點所使用的密碼
masterauth "123456"
# 監聽端口
port 6381
always-show-logo no

# 設定密碼認證
requirepass 123456
rename-command KEYS ""

slaveof 127.0.0.1 6379

# 設定連接主節點所使用的密碼
masterauth "123456"

3 命令啟動  docker-compose up -d

 

 如何搭建哨兵模式:

 1.在服務其中創建目錄

mkdir /usr/local/etc/redis/sentinel/sentinel -p
cd /usr/local/etc/redis/sentinel/sentinel

2.把文件夾sentinel,server 拉到這個目錄下

切換到sentinel目錄下下我們配置了三個文件 :docker-compose.yml  redis-sentinel-1.conf  redis-sentinel-2.conf  redis-sentinel-3.conf 分別配置內容如下 

version: '3'

services:
  redis-sentinel-1:
    image: redis
    container_name: redis-sentinel-1
    restart: always
    # 為了規避Docker中端口映射可能帶來的問題
    # 這里選擇使用host網絡
    network_mode: host
    volumes:
      - ./redis-sentinel-1.conf:/usr/local/etc/redis/redis-sentinel.conf
    # 指定時區,保證容器內時間正確
    environment:
      TZ: "Asia/Shanghai" 
    command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"]
  redis-sentinel-2:
    image: redis
    container_name: redis-sentinel-2
    restart: always
    network_mode: host
    volumes:
      - ./redis-sentinel-2.conf:/usr/local/etc/redis/redis-sentinel.conf
    environment:
      TZ: "Asia/Shanghai" 
    command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"]
  redis-sentinel-3:
    image: redis
    container_name: redis-sentinel-3
    restart: always
    network_mode: host
    volumes:
      - ./redis-sentinel-3.conf:/usr/local/etc/redis/redis-sentinel.conf
    environment:
      TZ: "Asia/Shanghai"
    command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"]
port 26379
requirepass 123456
sentinel monitor local-master 127.0.0.1 6379 2
sentinel auth-pass local-master 123456
# master在連續多長時間無法響應PING指令后,就會主觀判定節點下線,默認是30秒
# 格式:sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds local-master 30000
port 26380
requirepass 123456
sentinel monitor local-master 127.0.0.1 6379 2
sentinel auth-pass local-master 123456
# master在連續多長時間無法響應PING指令后,就會主觀判定節點下線,默認是30秒
# 格式:sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds local-master 30000
port 26381
requirepass 123456
sentinel monitor local-master 127.0.0.1 6379 2
sentinel auth-pass local-master 123456
# master在連續多長時間無法響應PING指令后,就會主觀判定節點下線,默認是30秒
# 格式:sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds local-master 30000

 3 命令啟動  docker-compose up -d

查看情況 docker ps -a

查看到哨兵的主從搭建的容器已經成功

進入哨兵的主節點:docker exec -it redis-serveer-master /bin/bash  =====>  redis-cli -a 123456  -h 192.168.1.211 -p 6380  ====> info replication  ====> set name gengen  =====> get name 測試一下 其他的從節點也進去 get name 看看 

讓后把主節點的redis 停掉  ====》 docker stop redis-server-master 

4 如果主節點回復了呢 ====》docker start redis-server-master  會自動回復原來的主從關系

 哨兵或者主從里面的數據問題:

1.腦裂問題

什么是redis的集群腦裂?
redis的集群腦裂是指因為網絡問題,導致redis master節點跟redis slave節點和sentinel集群處於不同的網絡分區,此時因為sentinel集群無法感知到master的存在,所以將slave節點提升為master節點。此時存在兩個不同的master節點,就像一個大腦分裂成了兩個。
集群腦裂問題中,如果客戶端還在基於原來的master節點繼續寫入數據,那么新的master節點將無法同步這些數據,當網絡問題解決之后,sentinel集群將原先的master節點降為slave節點,此時再從新的master中同步數據,將會造成大量的數據丟失。

出現了主節點和哨兵之間網絡原因,而且有多數以上的哨兵認為主節點宕機,則再從會從節點現在一個主,這個時候客戶端代碼還是可以連接到之前的主節點的,可以寫數據,此時哨兵選舉了新的主節點,然后之前的主網絡恢復了,然后之前的主節點備份現在的主節點數據,造成數據不完整。。。

2.異步復制數據丟失問題

因為是異步復制數據,如果主節點和從節點直接數據復制太慢,在這之間主節點宕機,而且是真的宕機,這個時候從節點替換主節點,丟失了數據。。

哨兵--不管怎么樣的配置都沒有辦法保證數據百分之白不丟失,只能盡可能少量丟數據

怎么解決上面這來個問題呢?

需要改配置文件:

1.至少有幾個從節點。配置=0,代表的是,當主節點和從節點之間互通的時候,發現從節點小於一個的時候,則從節點不會再繼續給客戶端提供服務。。 解決腦裂問題。。

2.偏移量配置。。。主節點和從節點數據之前偏移量只差,如果偏移量只差比配置小,則主節點也不會提供服務。。

解決方案
redis的配置文件中,存在兩個參數

min-slaves-to-write 3
min-slaves-max-lag 10

第一個參數表示連接到master的最少slave數量
第二個參數表示slave連接到master的最大延遲時間
按照上面的配置,要求至少3個slave節點,且數據復制和同步的延遲不能超過10秒,否則的話master就會拒絕寫請求,配置了這兩個參數之后,如果發生集群腦裂,原先的master節點接收到客戶端的寫入請求會拒絕,就可以減少數據同步之后的數據丟失。

注意:較新版本的redis.conf文件中的參數變成了

min-replicas-to-write 3
min-replicas-max-lag 10

 redis中的異步復制情況下的數據丟失問題也能使用這兩個參數

 

 

 

 

 

 

 


 

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM