redis哨兵模式的原理及部署

misakivv發表於2024-04-16

目錄
  • 一、什麼是哨兵模式
    • 1、為什麼需要哨兵機制
    • 2、哨兵架構拓撲
    • 3、Redis Sentinel的功能:
  • 二、搭建哨兵架構
    • 1、涉及主機
    • 2、拓撲結構
    • 3、設定一主兩從
    • 4、master伺服器狀態
    • 5、編輯哨兵的配置檔案
    • 6、啟動哨兵
    • 7、驗證哨兵埠
    • 8、檢視哨兵日誌
    • 9、驗證當前sentinel狀態
  • 三、故障轉移
    • 1、redis sentinel故障轉移的步驟:
    • 2、停止redis master
    • 3、檢視各個節點哨兵資訊
    • 4、檢視redis配置檔案
    • 5、檢視新master狀態
    • 6、恢復故障的原master重新加入redis叢集
  • 四、sentinel運維
    • 1、手動讓主節點下線

一、什麼是哨兵模式

Redis Sentinel 是一個分散式系統,為Redis提供高可用性解決方案。可以在一個架構中執行多個 Sentinel 程序(progress), 這些程序使用流言協議 (gossip protocols) 來接收關於主伺服器是否下線的資訊, 並使用投票協議(agreement protocols)來決定是否執行自動故障遷移,以及選擇哪個從伺服器作為新的主伺服器。

1、為什麼需要哨兵機制

在沒有哨兵機制的情況下,Redis主從叢集中若主節點發生故障,需要運維人員手動介入,識別故障、選擇合適的從節點提升為主節點,並更新所有客戶端的連線配置,使其指向新的主節點。這一過程既繁瑣又耗時,尤其是在緊急情況下可能導致服務長時間不可用。

2、哨兵架構拓撲

1132884-20180928145734973-1288883859

3、Redis Sentinel的功能:

  • 對Redis節點進行監控
  • 故障判斷
  • 故障轉移
  • 故障通知

二、搭建哨兵架構

1、涉及主機

角色 主機名 IP地址
主節點 master 192.168.112.40
從節點 slave2 192.168.112.50
從節點 slave1 192.168.112.60

2、拓撲結構

image-20240415225051989

3、設定一主兩從

所有節點:

[root@master ~]# vim /apps/redis/etc/redis.conf
bind 0.0.0.0
masterauth centos
requirepass centos
[root@master ~]# echo -e "net.core.somaxconn = 1024\nvm.overcommit_memory = 1" >> /etc/sysctl.conf
[root@master ~]# sysctl -p
net.core.somaxconn = 1024
vm.overcommit_memory = 1
net.core.somaxconn = 1024
vm.overcommit_memory = 1
[root@master ~]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
[root@master ~]# echo "echo never > /sys/kernel/mm/transparent_hugepage/enabled" >> /etc/rc.d/rc.local
[root@master ~]# chmod +x /etc/rc.d/rc.local
[root@master ~]# systemctl restart redis

slave節點:

[root@slave1 ~]# echo "replicaof 192.168.112.40 6379" >> /apps/redis/etc/redis.conf
[root@slave1 ~]# systemctl restart redis
[root@slave2 ~]# echo "replicaof 192.168.112.40 6379" >> /apps/redis/etc/redis.conf
[root@slave2 ~]# systemctl restart redis

4、master伺服器狀態

[root@master ~]# redis-cli -a centos --no-auth-warning
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.112.60,port=6379,state=online,offset=518,lag=0
slave1:ip=192.168.112.50,port=6379,state=online,offset=518,lag=0
master_replid:4f28bb9953f9850a433ae73a943fa02e607f691f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:518
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:518

5、編輯哨兵的配置檔案

Sentinel實際上是一個特殊的redis伺服器,有些redis指令支援,但很多指令並不支援.預設監聽在26379/tcp埠

哨兵可以不和Redis伺服器部署在一起,但一般部署在一起,所有redis節點使用相同的配置檔案

如果是編譯安裝,在原始碼目錄有sentinel.conf,複製到安裝目錄即可

image-20240416085526709

master節點:

[root@master ~]# cp redis-5.0.9/sentinel.conf /apps/redis/etc/
[root@master ~]# egrep -v "^#|^$" /apps/redis/etc/sentinel.conf
port 26379
daemonize no
pidfile /var/run/redis-sentinel.pid
logfile ""
dir /tmp  #工作目錄
sentinel monitor mymaster 127.0.0.1 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 <master-name> <password>
#mymaster叢集中master的密碼,注意此行要在上面行的下面
sentinel down-after-milliseconds mymaster 30000
#(SDOWN)判斷mymaster叢集中所有節點的主觀下線的時間,單位:毫秒,建議30000
sentinel parallel-syncs mymaster 1
#發生故障轉移後,同時向新master同步資料的slave數量,數字越小總同步時間越長,但可以減輕新master的負載壓力
sentinel failover-timeout mymaster 180000
#所有slaves指向新的master所需的超時時間,單位:毫秒
sentinel deny-scripts-reconfig yes
#禁止修改指令碼

修改所有的哨兵伺服器配置檔案

修改配置檔案前記得備份

#所有的哨兵伺服器都是如下配置,以master為例

[root@master ~]# egrep -v "^#|^$" /apps/redis/etc/sentinel.conf
port 26379
daemonize no
pidfile /apps/redis/run/redis-sentinel.pid
logfile "/apps/redis/log/sentinel.log"
dir /tmp
sentinel monitor mymaster 192.168.112.40 6379 2
sentinel auth-pass mymaster centos
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

6、啟動哨兵

所有主機

#新增哨兵服務
cat << EOF > /lib/systemd/system/redis-sentinel.service
[Unit]
Description=Redis Sentinel
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf --supervised systemd
ExecStop=/usr/libexec/redis-shutdown redis-sentinel
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
[root@master ~]# chown redis.redis /apps/redis/etc/sentinel.conf
#過載配置檔案
[root@master ~]# systemctl daemon-reload
# 確保每個哨兵主機myid不同
#在master上
[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl enable --now redis-sentinel
Created symlink from /etc/systemd/system/multi-user.target.wants/redis-sentinel.service to /usr/lib/systemd/system/redis-sentinel.service.
[root@master ~]# grep myid /apps/redis/etc/sentinel.conf
sentinel myid 331200834d2dbc801dfe3714051861683517b037
#在slave1上
[root@slave1 tmp]# systemctl daemon-reload
[root@slave1 tmp]# systemctl enable --now redis-sentinel
Created symlink from /etc/systemd/system/multi-user.target.wants/redis-sentinel.service to /usr/lib/systemd/system/redis-sentinel.service.
[root@slave1 tmp]# grep myid /apps/redis/etc/sentinel.conf
sentinel myid d67683381ceb20bf91fc965540bd88a76594b7f5
#在slave2上
[root@slave2 tmp]# systemctl daemon-reload
[root@slave2 tmp]# systemctl enable --now redis-sentinel
Created symlink from /etc/systemd/system/multi-user.target.wants/redis-sentinel.service to /usr/lib/systemd/system/redis-sentinel.service.
[root@slave2 tmp]# grep myid /apps/redis/etc/sentinel.conf
sentinel myid 4223fba33129fa40e8af93590900b2f3e5a8f81f

7、驗證哨兵埠

ss -tnl

image-20240416095421853

8、檢視哨兵日誌

[root@master ~]# tail /apps/redis/log/sentinel.log
1628:X 16 Apr 2024 09:43:19.697 # You requested maxclients of 10000 requiring at least 10032 max file descriptors.
1628:X 16 Apr 2024 09:43:19.697 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted.
1628:X 16 Apr 2024 09:43:19.697 # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
1628:X 16 Apr 2024 09:43:19.698 * Running mode=sentinel, port=26379.
1628:X 16 Apr 2024 09:43:19.702 # Sentinel ID is 331200834d2dbc801dfe3714051861683517b037
1628:X 16 Apr 2024 09:43:19.702 # +monitor master mymaster 192.168.112.40 6379 quorum 2
1628:X 16 Apr 2024 09:43:19.703 * +slave slave 192.168.112.50:6379 192.168.112.50 6379 @ mymaster 192.168.112.40 6379
1628:X 16 Apr 2024 09:43:19.703 * +slave slave 192.168.112.60:6379 192.168.112.60 6379 @ mymaster 192.168.112.40 6379
1628:X 16 Apr 2024 09:44:54.907 * +sentinel sentinel d67683381ceb20bf91fc965540bd88a76594b7f5 192.168.112.50 26379 @ mymaster 192.168.112.40 6379
1628:X 16 Apr 2024 09:45:47.791 * +sentinel sentinel 4223fba33129fa40e8af93590900b2f3e5a8f81f 192.168.112.60 26379 @ mymaster 192.168.112.40 6379

9、驗證當前sentinel狀態

master節點:

[root@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=192.168.112.40:6379,slaves=2,sentinels=3

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

三、故障轉移

1、redis sentinel故障轉移的步驟:

1.當某個master發生故障,多個sentinel會監控到這個異常,這些sentinel會按照一定規則從多個slave中選中一個做為新的master,並通知別的slave從新的master中同步資料
2.當某個slave轉換為新的master,sentinel會記錄新的master的地址資訊和slave的地址資訊,通知Redis cli
3.Redis cli接收到新的master和slave的資訊,就會向新的master寫入資料,從slave中讀取資料
4.等到原來的master重啟之後,會變成新的master的slave,並從新的master同步資料

img_8a1e5224a999b43622fdde0c0f246ced

2、停止redis master

yum install -y psmisc
[root@master ~]# killall redis-server

3、檢視各個節點哨兵資訊

slave1:

[root@slave1 ~]# 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=192.168.112.60:6379,slaves=2,sentinels=3

slave2:

[root@slave2 ~]# 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=192.168.112.60:6379,slaves=2,sentinels=3

4、檢視redis配置檔案

[root@slave1 ~]# grep "^replicaof" /apps/redis/etc/redis.conf
replicaof 192.168.112.60 6379
[root@slave1 ~]# grep monitor /apps/redis/etc/sentinel.conf
sentinel monitor mymaster 192.168.112.60 6379 2

5、檢視新master狀態

[root@slave2 ~]# redis-cli -a centos --no-auth-warning
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.112.50,port=6379,state=online,offset=392291,lag=1
master_replid:c647c550c9394542e4f43b5538b1bfc1f7d5fedd
master_replid2:b54e20a0f991557145e9df7367777e1da8256a6f
master_repl_offset:392434
second_repl_offset:238694
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:392434

6、恢復故障的原master重新加入redis叢集

[root@master ~]# systemctl restart redis
[root@master ~]# ss -tnl
State       Recv-Q Send-Q Local Address:Port               Peer Address:Port             
LISTEN      0      128              *:22                           *:*
LISTEN      0      100      127.0.0.1:25                           *:*
LISTEN      0      511              *:6379                         *:*
LISTEN      0      511              *:26379                        *:*
LISTEN      0      128           [::]:22                        [::]:*
LISTEN      0      100          [::1]:25                        [::]:*
LISTEN      0      511           [::]:26379                     [::]:*
[root@master ~]# grep "^replicaof" /apps/redis/etc/redis.conf
replicaof 192.168.112.60 6379
[root@master ~]# redis-cli -a centos --no-auth-warning
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.112.60
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:446146
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:c647c550c9394542e4f43b5538b1bfc1f7d5fedd
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:446146
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:438489
repl_backlog_histlen:7658

四、sentinel運維

1、手動讓主節點下線

# 指定優先順序,值越小sentinel會優先將之選為新的master,默為值為100
[root@master ~]# vim /apps/redis/etc/redis.conf
replica-priority 10
[root@master ~]# systemctl restart redis
[root@master ~]# redis-cli -p 26379
127.0.0.1:26379> sentinel failover mymaster            #手動發起哨兵切換
OK
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=192.168.112.40:6379,slaves=2,sentinels=3

相關文章