詳解,Redis 哨兵(Sentinel)工做原理,實現及哨兵運維

Redis 哨兵(Sentinel)

在生產過程當中,咱們會遇到主master從slave切換,當主(master)服務器出現redis服務器異常,主機斷電,磁盤損壞,等問題時候後,而redis主從複製沒法實現自動的故障轉移(將slave 自動提高爲新
master),須要手動把一臺從服務器切換爲主服務器,這個步驟須要人工切換,費時費力,還有可能形成"事故",另外也沒法橫向擴展Redis服務的並行寫入性能,當單臺Redis服務器性能沒法知足業務寫入需求的時候,也須要解決以上的兩個核心問題因此這個時候咱們會哨兵模式幫咱們解決,從而幫助咱們實現多臺服務器並行寫入已實現更高的併發問題的目的.
redis

下面咱們咱們介紹下算法

詳解,Redis 哨兵(Sentinel)工做原理,實現及哨兵運維

哨兵(Sentinel)工做原理概述

sentinel 架構和故障轉移
詳解,Redis 哨兵(Sentinel)工做原理,實現及哨兵運維
vim

詳解,Redis 哨兵(Sentinel)工做原理,實現及哨兵運維
詳解,Redis 哨兵(Sentinel)工做原理,實現及哨兵運維

Sentinel 進程是用於監控redis集羣中Master主服務器工做的狀態,在Master主服務器發生故障的時候,能夠實現Master和Slave服務器的切換,保證系統的高可用,此功能在redis2.6+的版本已引用,Redis的哨兵模式到了2.8版本以後就穩定了下來。通常在生產環境也建議使用Redis的2.8版本的之後版本centos

哨兵(Sentinel) 是一個分佈式系統,能夠在一個架構中運行多個哨兵(sentinel) 進程,這些進程使用流言協議(gossip protocols)來接收關於Master主服務器是否下線的信息,並使用投票協議(Agreement Protocols)來決定是否執行自動故障遷移,以及選擇哪一個Slave做爲新的Masterbash

每一個哨兵(Sentinel)進程會向其它哨兵(Sentinel)、Master、Slave定時發送消息,以確認對方是否」活」着,若是發現對方在指定配置時間(此項可配置)內未獲得迴應,則暫時認爲對方已離線,也就是所謂的」主觀認爲宕機」 (主觀:是每一個成員都具備的獨自的並且可能相同也可能不一樣的意識),英文名稱:Subjective Down,簡稱SDOWN服務器

主觀下線和客觀下線架構

有主觀宕機,對應的有客觀宕機。當「哨兵羣」中的多數Sentinel進程在對Master主服務器作出SDOWN的判斷,而且經過 SENTINEL is-master-down-by-addr 命令互相交流以後,得出的Master Server下線判斷,這種方式就是「客觀宕機」(客觀:是不依賴於某種意識而已經實際存在的一切事物),英文名稱是:Objectively Down, 簡稱 ODOWN併發

  • 當一個主服務器被斷定爲客觀下線之後,監視這個服務器的各個Sentinel會進行協商,選舉出一個領頭的Sentinel,並由領頭Sentinel對下線主服務器進行故障轉移。
  • 每通過一次選舉,不管選舉成功仍是失敗,每隔sentinel實例的配置紀元都會自增1,每一個新的紀元中,任何一個sentinel都有可能成爲領頭Sentinel。

經過必定的vote算法,從剩下的slave從服務器節點中,選一臺提高爲Master服務器節點,而後自動修改相關配置,並開啓故障轉移(failover)app

Sentinel 機制能夠解決master和slave角色的自動切換問題,但單個 Master 的性能瓶頸問題沒法解決,相似於MySQL中的MHA功能運維

注意事項:

  • Redis Sentinel中的Sentinel節點個數應該爲大於等於3且最好爲奇數
  • 客戶端初始化時鏈接的是Sentinel節點集合,再也不是具體的Redis節點,但Sentinel只是配置中心不是代理
  • Redis Sentinel 節點與普通redis 沒有區別,要實現讀寫分離依賴於客戶端程序
  • redis 3.0 以前版本中,生產環境通常使用哨兵模式,但3.0後推出redis cluster功能後,能夠支持更大規模的生產環境

sentinel中的三個定時任務

  • 第一個定時

  • 每10秒每一個sentinel對master和slave執行info

    • 發現slave節點
    • 確認主從關係

詳解,Redis 哨兵(Sentinel)工做原理,實現及哨兵運維

  • 第二個定時

  • 每2秒每一個sentinel經過master節點的channel交換信息(pub/sub)

    • 經過sentinel__:hello頻道交互
    • 交互對節點的「見解」和自身信息
      詳解,Redis 哨兵(Sentinel)工做原理,實現及哨兵運維
  • 第三個定時

  • 每1秒每一個sentinel對其餘sentinel和redis執行ping

    心跳檢測,失敗斷定的依據

詳解,Redis 哨兵(Sentinel)工做原理,實現及哨兵運維

如何實現哨兵

詳解,Redis 哨兵(Sentinel)工做原理,實現及哨兵運維
注意哨兵的準備實現主從複製架構

哨兵的前提是已經實現了一個redis的主從複製的運行環境,從而實現一個一主兩從基於哨兵的高可用redis架構
注意: master 的配置文件中masterauth 和slave 都必須相同
master和slave同步過程
一、從節點主動向主節點發送同步請求


二、主節點接收到從的消息後發送本身的runid和offset發送給從節點

三、從節點保存主節點發送過來的runid和offset

四、主節點後臺執行RDB持久化,並將新寫入的數據寫入到緩衝區中

五、主節點將RDB文件發送到從節點

六、主節點在把RDB文件發送到從節點後,把buffer中的數據以redis協議格式發送到從節點

七、從節點清空本身舊的數據

八、從節點把主節點推送過來的RDB文件中的數據載入內存,再加載全部緩衝區中的內容完成全量同步

九、全量同步完成後,如從節點須要繼續同步增量數據的話,會先將本身的offset位置發送給主節點,主節點在收到後會根據從節點的offset,將從節點offset位置以後的數據發送回從節點,同時也將在緩衝區的數據也發送給從節點

全部主從節點的redis.conf中關健配置

實踐範例:

#在全部主從節點執行
[root@centos8 ~]#dnf -y install redis
[root@centos8 ~]#vim /etc/redis.conf
bind 0.0.0.0
masterauth "123456"
requirepass "123456"
#或者非交互執行

[root@centos8 ~]#sed -i -e 's/bind 127.0.0.1/bind 0.0.0.0/' -e 's/^# masterauth
.*/masterauth 123456/' -e 's/^# requirepass .*/requirepass 123456/'
/etc/redis.conf
#在全部從節點執行

[root@centos8 ~]#echo "replicaof 10.0.0.8 6379" >> /etc/redis.conf
#在全部主從節點執行

[root@centos8 ~]#systemctl enable --now redis

master服務器狀態

[root@redis-master ~]#redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface
may not
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=10.0.0.28,port=6379,state=online,offset=112,lag=1
slave1:ip=10.0.0.18,port=6379,state=online,offset=112,lag=0
master_replid:8fdca730a2ae48fb9c8b7e739dcd2efcc76794f3
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:112
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:112
127.0.0.1:6379>

配置slave1

[root@redis-slave1 ~]#redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface
may not be safe.
127.0.0.1:6379> REPLICAOF 10.0.0.8 6379
OK
127.0.0.1:6379> CONFIG SET masterauth "123456"
OK
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:10.0.0.8
master_port:6379
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_repl_offset:140
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:8fdca730a2ae48fb9c8b7e739dcd2efcc76794f3
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:140
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_

配置slave2

[root@redis-slave2 ~]#redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface
may not be safe.
127.0.0.1:6379> REPLICAOF 10.0.0.8 6379
OK
127.0.0.1:6379> CONFIG SET masterauth "123456"
OK
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:10.0.0.8
master_port:6379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:182
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:8fdca730a2ae48fb9c8b7e739dcd2efcc76794f3
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:182
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:168
127.0.0.1:6379>

編輯哨兵的配置文件

sentinel配置

  • Sentinel其實是一個特殊的redis服務器,有些redis指令支持,但不少指令並不支持.默認監聽在26379/tcp端口.
  • 哨兵能夠不和Redis服務器部署在一塊兒,但通常部署在一塊兒,全部redis節點使用相同的如下示例的配置文件
#若是是編譯安裝,在源碼目錄有sentinel.conf,複製到安裝目錄便可,
如:/apps/redis/etc/sentinel.conf

[root@centos8 ~]#vim /etc/redis-sentinel.conf
bind 0.0.0.0
port 26379
daemonize yes
pidfile "redis-sentinel.pid"
logfile "sentinel_26379.log"
dir "/tmp"  #工做目錄

sentinel monitor mymaster 10.0.0.8 6379 2 #指定當前mymaster集羣中master服務器的地址和端口
#2爲法定人數限制(quorum),即有幾個sentinel認爲master down了就進行故障轉移,通常此值是全部sentinel節點(通常總數是>=3的 奇數,如:3,5,7等)的一半以上的整數值,好比,總數是3,即3/2=1.5,取整爲2,是master的ODOWN客觀下線的依據

sentinel auth-pass mymaster 123456 #mymaster集羣中master的密碼,注意此行要在上面行的下面

sentinel down-after-milliseconds mymaster 30000 #(SDOWN)判斷mymaster集羣中全部節點的主觀下線的時間,單位:毫秒,建議3000

sentinel parallel-syncs mymaster 1 #發生故障轉移後,同時向新master同步數據的slave數量,數字越小總同步時間越長,但能夠減輕新master的負載壓力

sentinel failover-timeout mymaster 180000 #全部slaves指向新的master所需的超時時間,單位:毫秒

sentinel deny-scripts-reconfig yes #禁止修改腳本

logfile /var/log/redis/sentinel.log

三個哨兵服務器的配置都以下

[root@redis-master ~]#grep -vE "^#|^$" /etc/redis-sentinel.conf
port 26379
daemonize no
pidfile "/var/run/redis-sentinel.pid"
logfile "/var/log/redis/sentinel.log"
dir "/tmp"
sentinel monitor mymaster 10.0.0.8 6379 2  #修改此行
sentinel auth-pass mymaster 123456 #增長此行
sentinel down-after-milliseconds mymaster 3000  #修改此行
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
#如下內容自動生成,不須要修改
sentinel myid 50547f34ed71fd48c197924969937e738a39975b  #此行自動生成必須惟一,修改此
值需重啓redis和sentinel服務
.....
# Generated by CONFIG REWRITE
protected-mode no
supervised systemd
sentinel leader-epoch mymaster 0
sentinel known-replica mymaster 10.0.0.28 6379
sentinel known-replica mymaster 10.0.0.18 6379
sentinel current-epoch 0

[root@redis-master ~]#scp /etc/redis-sentinel.conf redis-slave1:/etc/

[root@redis-master ~]#scp /etc/redis-sentinel.conf redis-slave2:/etc/

啓動哨兵

三臺哨兵服務器都要啓動

#確保每一個哨兵主機myid不一樣
[root@redis-slave1 ~]#vim /etc/redis-sentinel.conf
sentinel myid 50547f34ed71fd48c197924969937e738a39975c
[root@redis-slave2 ~]#vim /etc/redis-sentinel.conf
sentinel myid 50547f34ed71fd48c197924969937e738a39975d
[root@redis-master ~]#systemctl enable --now redis-sentinel.service
[root@redis-slave1 ~]#systemctl enable --now redis-sentinel.service
[root@redis-slave2 ~]#systemctl enable --now redis-sentinel.service

若是是編譯安裝,在全部哨兵服務器執行下面操做啓動哨兵

#vim /apps/redis/etc/sentinel.conf
bind 0.0.0.0
port 26379
daemonize yes
pidfile "redis-sentinel.pid"
Logfile "sentinel_26379.log"
dir "/apps/redis/data"
sentinel monitor mymaster 10.0.0.8 6379 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 15000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

#/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf

驗證哨兵端口

[root@redis-master ~]#ss -ntl
State    Recv-Q    Send-Q   Local Address:Port   Peer Address:Port
   
LISTEN    0       128        0.0.0.0:22       0.0.0.0:*  
  
LISTEN    0       128        0.0.0.0:26379     0.0.0.0:*  
  
LISTEN    0       128        0.0.0.0:6379      0.0.0.0:*  
  
LISTEN    0       128         [::]:22        [::]:*  
  
LISTEN    0       128         [::]:26379      [::]:*  
  
LISTEN    0       128         [::]:6379       [::]:*

查看哨兵日誌

master的哨兵日誌

[root@redis-master ~]#tail -f /var/log/redis/sentinel.log
38028:X 20 Feb 2020 17:13:08.702 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
38028:X 20 Feb 2020 17:13:08.702 # Redis version=5.0.3, bits=64,
commit=00000000, modified=0, pid=38028, just started
38028:X 20 Feb 2020 17:13:08.702 # Configuration loaded
38028:X 20 Feb 2020 17:13:08.702 * supervised by systemd, will signal readiness
38028:X 20 Feb 2020 17:13:08.703 * Running mode=sentinel, port=26379.
38028:X 20 Feb 2020 17:13:08.703 # WARNING: The TCP backlog setting of 511
cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower
value of 128.
38028:X 20 Feb 2020 17:13:08.704 # Sentinel ID is
50547f34ed71fd48c197924969937e738a39975b
38028:X 20 Feb 2020 17:13:08.704 # +monitor master mymaster 10.0.0.8 6379 quorum
2
38028:X 20 Feb 2020 17:13:08.709 * +slave slave 10.0.0.28:6379 10.0.0.28 6379 @
mymaster 10.0.0.8 6379
38028:X 20 Feb 2020 17:13:08.709 * +slave slave 10.0.0.18:6379 10.0.0.18 6379 @
mymaster 10.0.0.8 6379

slave的哨兵日誌

root@redis-slave1 ~]#tail -f /var/log/redis/sentinel.log
25509:X 20 Feb 2020 17:13:27.435 * Removing the pid file.
25509:X 20 Feb 2020 17:13:27.435 # Sentinel is now ready to exit, bye bye...
25572:X 20 Feb 2020 17:13:27.448 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
25572:X 20 Feb 2020 17:13:27.448 # Redis version=5.0.3, bits=64,
commit=00000000, modified=0, pid=25572, just started
25572:X 20 Feb 2020 17:13:27.448 # Configuration loaded
25572:X 20 Feb 2020 17:13:27.448 * supervised by systemd, will signal readiness
25572:X 20 Feb 2020 17:13:27.449 * Running mode=sentinel, port=26379.
25572:X 20 Feb 2020 17:13:27.449 # WARNING: The TCP backlog setting of 511
cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower
value of 128.
25572:X 20 Feb 2020 17:13:27.449 # Sentinel ID is
50547f34ed71fd48c197924969937e738a39975b
25572:X 20 Feb 2020 17:13:27.449 # +monitor master mymaster 10.0.0.8 6379 quorum2

當前sentinel狀態

在sentinel狀態中尤爲是最後一行,涉及到masterIP是多少,有幾個slave,有幾個sentinels,必須是符合所有服務器數量

[root@redis-master ~]#redis-cli -p 26379
127.0.0.1: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=10.0.0.8:6379,slaves=2,sentinels=3 #兩個
slave,三個sentinel服務器,若是sentinels值不符合,檢查myid可能衝突

中止Redis Master測試故障轉移

[root@redis-master ~]#killall redis-server

查看各節點上哨兵信息:

[root@redis-master ~]#redis-cli -a 123456 -p 26379
Warning: Using a password with '-a' or '-u' option on the command line interface
may not be safe.
127.0.0.1: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=10.0.0.18:6379,slaves=2,sentinels=2
相關文章
相關標籤/搜索