【Redis】Setninel 哨兵机制

2023-06-26,,

一、Sentinel 哨兵工作原理

Redis在2.6+以后引入哨兵机制,在2.8版本后趋于稳定状态,在生产环境中建议使用2.8版本以上的sentinel服务。sentinel集群用于监控redis集群中Master节点工作状态,在Master节点发生故障时,可以实现主从切换,保证系统的高可用。

哨兵(Sentinel)是一个分布式集群架构,可在一个架构中运行多个Sentinel进程,这些进程使用流言协议(gossip protocols)l来接收关于master节点是否故障的信息,并使用投票协议(vote protocols)来决定是否执行故障切换,以及选择使用哪一个slave节点提升为master。哨兵机制可以解决故障发生时master与slave的自动切换,但无法解决单机性能瓶颈。
每个哨兵(Sentinel)进程会定时向其他节点(Sentinel、Master、Slave)发送消息,当对方节点在指定配置时间内没有进行回应,则判定该节点故障,这个过程就是“主观认为宕机”(Subjective down),简称sdown。每个节点判定sdown状态的结果可能相同或不同。
当同一个哨兵集群中的多个(超过集群节点数一半以上)sentinel进程判定Master节点发生sdown后,并通过 SENTINEL is master down-by-addr 命令进行信息同步交流后,最终判定Master节点发生故障,这个通常称之为“客观宕机”(Objectively down),简称odown。
当哨兵集群判定Master发生odown后,通过一定vote算法从其余正常的slave节点中选举出一台服务器提升为Master节点,然后自动修改相关配置,并开启故障转移(failover)
客户端初始连接配置,应该选择连接Sentinel节点集合,而不再是单独连接redis节点,并声明选择连接的redis主节点或集群名称(Master name),Sentinel接收到客户端请求将会返回消息通知客户端Master节点和Slave节点信息,由客户端程序执行相应请求(Sentinel节点仅作为配置中心,而非proxy代理)。
哨兵集群节点个数应该要配置为 大于或等于3的奇数

二、Sentinel哨兵配置文件详解

# Example sentinel.conf

# 哨兵sentinel实例运行的端口 默认26379
port 26379 # 哨兵sentinel的工作目录
dir /tmp # 哨兵sentinel监控的redis主节点的 ip port
# master-name 可以自己命名的主节点名字 只能由字母A-z、数字0-9 、这三个字符".-_"组成。
# quorum 当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 2 # 当在Redis实例中开启了requirepass foobared 授权密码 这样所有连接Redis实例的客户端都要提供密码
# 设置哨兵sentinel 连接主从的密码 注意必须为主从设置一样的验证密码
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster MySUPER--secret-0123passw0rd # 指定多少毫秒之后 主节点没有应答哨兵sentinel 此时 哨兵主观上认为主节点下线 默认30秒
# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 30000 # 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,
这个数字越小,完成failover所需的时间就越长,
但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。
可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。
# sentinel parallel-syncs <master-name> <numslaves>
sentinel parallel-syncs mymaster 1 # 故障转移的超时时间 failover-timeout 可以用在以下这些方面:
#1. 同一个sentinel对同一个master两次failover之间的间隔时间。
#2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。
#3.当想要取消一个正在进行的failover所需要的时间。
#4.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了
# 默认三分钟
# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000 # SCRIPTS EXECUTION #配置当某一事件发生时所需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时发邮件通知相关人员。
#对于脚本的运行结果有以下规则:
#若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10
#若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。
#如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同。
#一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被一个SIGKILL信号终止,之后重新执行。 #通知型脚本:当sentinel有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等等),将会去调用这个脚本,
这时这个脚本应该通过邮件,SMS等方式去通知系统管理员关于系统不正常运行的信息。调用该脚本时,将传给脚本两个参数,
一个是事件的类型,
一个是事件的描述。
如果sentinel.conf配置文件中配置了这个脚本路径,那么必须保证这个脚本存在于这个路径,并且是可执行的,否则sentinel无法正常启动成功。
#通知脚本
# sentinel notification-script <master-name> <script-path>
sentinel notification-script mymaster /var/redis/notify.sh # 客户端重新配置主节点参数脚本
# 当一个master由于failover而发生改变时,这个脚本将会被调用,通知相关的客户端关于master地址已经发生改变的信息。
# 以下参数将会在调用脚本时传给脚本:
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
# 目前<state>总是“failover”,
# <role>是“leader”或者“observer”中的一个。
# 参数 from-ip, from-port, to-ip, to-port是用来和旧的master和新的master(即旧的slave)通信的
# 这个脚本应该是通用的,能被多次调用,不是针对性的。
# sentinel client-reconfig-script <master-name> <script-path>
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh

三、Sentinel哨兵机制部署

1、哨兵机制主从架构准备

#master节点redis配置文件修改内容
[root@Redis-Ubuntu-1804-p20:~]# cat /app/redis/etc/redis_6380.conf | grep -e "^bind\|^masterauth\|^replicaof\|^requirepass"
bind 0.0.0.0
masterauth redis
requirepass redis
[root@Redis-Ubuntu-1804-p20:~]# #slave节点redis配置文件修改内容
[root@Redis-Ubuntu-1804-p21:~]# cat /redis/etc/redis_6380.conf | grep -e "^bind\|^masterauth\|^replicaof\|^requirepass"
cat: /redis/etc/redis_6380.conf: No such file or directory
[root@Redis-Ubuntu-1804-p21:~]# cat /app/redis/etc/redis_6380.conf | grep -e "^bind\|^masterauth\|^replicaof\|^requirepass"
bind 0.0.0.0
replicaof 10.0.0.20 6380
masterauth redis
requirepass redis
[root@Redis-Ubuntu-1804-p21:~]# [root@Redis-Ubuntu-1804-p22:~]# cat /redis/etc/redis_6380.conf | grep -e "^bind\|^masterauth\|^replicaof\|^requirepass"
cat: /redis/etc/redis_6380.conf: No such file or directory
[root@Redis-Ubuntu-1804-p22:~]# cat /app/redis/etc/redis_6380.conf | grep -e "^bind\|^masterauth\|^replicaof\|^requirepass"
bind 0.0.0.0
replicaof 10.0.0.20 6380
masterauth redis
requirepass redis
[root@Redis-Ubuntu-1804-p22:~]#

2、修改配置启动sentinel

#在每个节点上创建sentinel配置文件
[root@Redis-Ubuntu-1804-p20:~]# cat > /app/redis/etc/sentinel.conf <<EOF
port 26379
daemonize yes
pidfile /app/redis/run/redis-sentinel.pid
logfile "/app/redis/log/sentinel.log"
dir /app/redis
sentinel monitor mymaster 10.0.0.20 6380 2
sentinel auth-pass mymaster redis
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
EOF
#启动sentinel
[root@Redis-Ubuntu-1804-p20:~]# redis-sentinel /app/redis/etc/sentinel.conf
[root@Redis-Ubuntu-1804-p20:~]# ss -ntlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 511 0.0.0.0:26379 0.0.0.0:* users:(("redis-sentinel",pid=2702,fd=7))
LISTEN 0 511 0.0.0.0:6379 0.0.0.0:* users:(("redis-server",pid=851,fd=6))
LISTEN 0 511 0.0.0.0:6380 0.0.0.0:* users:(("redis-server",pid=2101,fd=6))
LISTEN 0 511 0.0.0.0:6381 0.0.0.0:* users:(("redis-server",pid=881,fd=6))
LISTEN 0 128 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=801,fd=13))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=885,fd=3))
LISTEN 0 128 127.0.0.1:6010 0.0.0.0:* users:(("sshd",pid=1467,fd=10))
LISTEN 0 511 [::]:26379 [::]:* users:(("redis-sentinel",pid=2702,fd=6))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=885,fd=4))
LISTEN 0 128 [::1]:6010 [::]:* users:(("sshd",pid=1467,fd=9))

  

3、观察sentinel配置文件变化

##启动后对比配置文件变化
[root@Redis-Ubuntu-1804-p20:~]# cat /app/redis/etc/sentinel.conf
port 26379
daemonize yes
pidfile "/app/redis/run/redis-sentinel.pid"
logfile "/app/redis/log/sentinel.log"
dir "/app/redis"
sentinel myid 4e21cfb28d765283301f98584961adc0d755ac21 ##每个sentinel节点的id都需确保不同
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 10.0.0.20 6380 2
sentinel auth-pass mymaster redis
sentinel config-epoch mymaster 0
# Generated by CONFIG REWRITE
protected-mode no
sentinel leader-epoch mymaster 0
sentinel known-replica mymaster 10.0.0.22 6380
sentinel known-replica mymaster 10.0.0.21 6380
sentinel known-sentinel mymaster 10.0.0.22 26379 f41684db3a063d4468b5023f57c62a7a5bb3130e
sentinel known-sentinel mymaster 10.0.0.21 26379 49b72e4d02964472051d55fd2980dd598332ac9f
sentinel current-epoch 0 [root@Redis-Ubuntu-1804-p21:~]# cat /app/redis/etc/sentinel.conf
port 26379
daemonize yes
pidfile "/app/redis/run/redis-sentinel.pid"
logfile "/app/redis/log/sentinel.log"
dir "/app/redis"
sentinel myid 49b72e4d02964472051d55fd2980dd598332ac9f ##每个sentinel节点的id都需确保不同
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 10.0.0.20 6380 2
sentinel auth-pass mymaster redis
sentinel config-epoch mymaster 0
# Generated by CONFIG REWRITE
protected-mode no
sentinel leader-epoch mymaster 0
sentinel known-replica mymaster 10.0.0.22 6380
sentinel known-replica mymaster 10.0.0.21 6380
sentinel known-sentinel mymaster 10.0.0.20 26379 4e21cfb28d765283301f98584961adc0d755ac21
sentinel known-sentinel mymaster 10.0.0.22 26379 f41684db3a063d4468b5023f57c62a7a5bb3130e
sentinel current-epoch 0 [root@Redis-Ubuntu-1804-p22:~]# cat /app/redis/etc/sentinel.conf
port 26379
daemonize yes
pidfile "/app/redis/run/redis-sentinel.pid"
logfile "/app/redis/log/sentinel.log"
dir "/app/redis"
sentinel myid f41684db3a063d4468b5023f57c62a7a5bb3130e ##每个sentinel节点的id都需确保不同
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 10.0.0.20 6380 2
sentinel auth-pass mymaster redis
sentinel config-epoch mymaster 0
# Generated by CONFIG REWRITE
protected-mode no
sentinel leader-epoch mymaster 0
sentinel known-replica mymaster 10.0.0.21 6380
sentinel known-replica mymaster 10.0.0.22 6380
sentinel known-sentinel mymaster 10.0.0.21 26379 49b72e4d02964472051d55fd2980dd598332ac9f
sentinel known-sentinel mymaster 10.0.0.20 26379 4e21cfb28d765283301f98584961adc0d755ac21
sentinel current-epoch 0

  

4、查看sentinel状态

[root@Redis-Ubuntu-1804-p20:~]# redis-cli -a redis -p 26379 --no-auth-warning 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.20:6380,slaves=2,sentinels=3 [root@Redis-Ubuntu-1804-p21:~]# redis-cli -a redis -p 26379 --no-auth-warning 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.20:6380,slaves=2,sentinels=3 [root@Redis-Ubuntu-1804-p22:~]# redis-cli -a redis -p 26379 --no-auth-warning 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.20:6380,slaves=2,sentinels=3

  

python 脚本连接sentinel进行数据写入

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
#********************************************************************
#Author: janzen
#Date: 2023-04-18
#FileName: redis_sentinel_newData.py
#Description: The python3 script
#Copyright (C): 2023 All rights reserved
#********************************************************************
import redis
from redis.sentinel import Sentinel
import sys,time
key=sys.argv[1]
value=sys.argv[2]
num=1
redis_auth_pass='redis'
mastername='mymaster'
sentinel = Sentinel([
('10.0.0.20',26379),
('10.0.0.21',26379),
('10.0.0.22',26379)],
socket_timeout=0.5
)
while 1:
time.sleep(0.5)
try:
master = sentinel.discover_master(mastername)
slave = sentinel.discover_slaves=(mastername)
print("Master:%s ; Slave:%s" % (master,slave))
master = sentinel.master_for(mastername,socket_timeout=0.5,password=redis_auth_pass,db=0)
w_ret=master.set(key+str(num),value+str(num)) slave = sentinel.slave_for(mastername,socket_timeout=0.5,password=redis_auth_pass,db=0)
r_ret=master.get(key)
print("get data %s:%s" % (key+str(num),r_ret))
except Exception as err:
print(err)
continue
num+=1

5、模拟故障观察结果

[root@Redis-Ubuntu-1804-p20:~]# systemctl stop redis_6380.service 

三个节点日志

##10.0.0.20:26379
2702:X 18 Apr 2023 05:23:31.362 # +sdown master mymaster 10.0.0.20 6380
2702:X 18 Apr 2023 05:23:31.464 # +odown master mymaster 10.0.0.20 6380 #quorum 2/2
2702:X 18 Apr 2023 05:23:31.464 # +new-epoch 11
2702:X 18 Apr 2023 05:23:31.464 # +try-failover master mymaster 10.0.0.20 6380
2702:X 18 Apr 2023 05:23:31.465 # +vote-for-leader 4e21cfb28d765283301f98584961adc0d755ac21 11
2702:X 18 Apr 2023 05:23:31.477 # 49b72e4d02964472051d55fd2980dd598332ac9f voted for 4e21cfb28d765283301f98584961adc0d755ac21 11
2702:X 18 Apr 2023 05:23:31.477 # f41684db3a063d4468b5023f57c62a7a5bb3130e voted for 4e21cfb28d765283301f98584961adc0d755ac21 11
2702:X 18 Apr 2023 05:23:31.556 # +elected-leader master mymaster 10.0.0.20 6380
2702:X 18 Apr 2023 05:23:31.557 # +failover-state-select-slave master mymaster 10.0.0.20 6380
2702:X 18 Apr 2023 05:23:31.609 # +selected-slave slave 10.0.0.22:6380 10.0.0.22 6380 @ mymaster 10.0.0.20 6380
2702:X 18 Apr 2023 05:23:31.610 * +failover-state-send-slaveof-noone slave 10.0.0.22:6380 10.0.0.22 6380 @ mymaster 10.0.0.20 6380
2702:X 18 Apr 2023 05:23:31.711 * +failover-state-wait-promotion slave 10.0.0.22:6380 10.0.0.22 6380 @ mymaster 10.0.0.20 6380
2702:X 18 Apr 2023 05:23:32.236 # +promoted-slave slave 10.0.0.22:6380 10.0.0.22 6380 @ mymaster 10.0.0.20 6380
2702:X 18 Apr 2023 05:23:32.237 # +failover-state-reconf-slaves master mymaster 10.0.0.20 6380
2702:X 18 Apr 2023 05:23:32.289 * +slave-reconf-sent slave 10.0.0.21:6380 10.0.0.21 6380 @ mymaster 10.0.0.20 6380
2702:X 18 Apr 2023 05:23:32.499 * +slave-reconf-inprog slave 10.0.0.21:6380 10.0.0.21 6380 @ mymaster 10.0.0.20 6380
2702:X 18 Apr 2023 05:23:32.551 # -odown master mymaster 10.0.0.20 6380
2702:X 18 Apr 2023 05:23:33.516 * +slave-reconf-done slave 10.0.0.21:6380 10.0.0.21 6380 @ mymaster 10.0.0.20 6380
2702:X 18 Apr 2023 05:23:33.598 # +failover-end master mymaster 10.0.0.20 6380
2702:X 18 Apr 2023 05:23:33.598 # +switch-master mymaster 10.0.0.20 6380 10.0.0.22 6380
2702:X 18 Apr 2023 05:23:33.599 * +slave slave 10.0.0.21:6380 10.0.0.21 6380 @ mymaster 10.0.0.22 6380
2702:X 18 Apr 2023 05:23:33.599 * +slave slave 10.0.0.20:6380 10.0.0.20 6380 @ mymaster 10.0.0.22 6380
2702:X 18 Apr 2023 05:24:03.600 # +sdown slave 10.0.0.20:6380 10.0.0.20 6380 @ mymaster 10.0.0.22 6380

##10.0.0.21:26379
2553:X 18 Apr 2023 05:23:31.416 # +sdown master mymaster 10.0.0.20 6380
2553:X 18 Apr 2023 05:23:31.474 # +new-epoch 11
2553:X 18 Apr 2023 05:23:31.482 # +vote-for-leader 4e21cfb28d765283301f98584961adc0d755ac21 11
2553:X 18 Apr 2023 05:23:31.507 # +odown master mymaster 10.0.0.20 6380 #quorum 3/2
2553:X 18 Apr 2023 05:23:31.507 # Next failover delay: I will not start a failover before Tue Apr 18 05:29:32 2023
2553:X 18 Apr 2023 05:23:32.296 # +config-update-from sentinel 4e21cfb28d765283301f98584961adc0d755ac21 10.0.0.20 26379 @ mymaster 10.0.0.20 6380
2553:X 18 Apr 2023 05:23:32.297 # +switch-master mymaster 10.0.0.20 6380 10.0.0.22 6380
2553:X 18 Apr 2023 05:23:32.297 * +slave slave 10.0.0.21:6380 10.0.0.21 6380 @ mymaster 10.0.0.22 6380
2553:X 18 Apr 2023 05:23:32.297 * +slave slave 10.0.0.20:6380 10.0.0.20 6380 @ mymaster 10.0.0.22 6380
2553:X 18 Apr 2023 05:24:02.315 # +sdown slave 10.0.0.20:6380 10.0.0.20 6380 @ mymaster 10.0.0.22 6380

##10.0.0.22:26379
5545:X 18 Apr 2023 05:23:31.326 # +sdown master mymaster 10.0.0.20 6380
5545:X 18 Apr 2023 05:23:31.465 # +new-epoch 11
5545:X 18 Apr 2023 05:23:31.474 # +vote-for-leader 4e21cfb28d765283301f98584961adc0d755ac21 11
5545:X 18 Apr 2023 05:23:32.287 # +config-update-from sentinel 4e21cfb28d765283301f98584961adc0d755ac21 10.0.0.20 26379 @ mymaster 10.0.0.20 6380
5545:X 18 Apr 2023 05:23:32.288 # +switch-master mymaster 10.0.0.20 6380 10.0.0.22 6380
5545:X 18 Apr 2023 05:23:32.288 * +slave slave 10.0.0.21:6380 10.0.0.21 6380 @ mymaster 10.0.0.22 6380
5545:X 18 Apr 2023 05:23:32.288 * +slave slave 10.0.0.20:6380 10.0.0.20 6380 @ mymaster 10.0.0.22 6380
5545:X 18 Apr 2023 05:24:02.317 # +sdown slave 10.0.0.20:6380 10.0.0.20 6380 @ mymaster 10.0.0.22 6380

##写程序

Master:('10.0.0.20', 6380) ; Slave:mymaster
set data key_229:b'value_229'
Master:('10.0.0.20', 6380) ; Slave:mymaster
set data key_230:b'value_230'
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
Master:('10.0.0.20', 6380) ; Slave:mymaster
Error 111 connecting to 10.0.0.20:6380. Connection refused.
No master found for 'mymaster'
Master:('10.0.0.22', 6380) ; Slave:mymaster
set data key_231:b'value_231'
Master:('10.0.0.22', 6380) ; Slave:mymaster
set data key_232:b'value_232'
Master:('10.0.0.22', 6380) ; Slave:mymaster
set data key_233:b'value_233'
Master:('10.0.0.22', 6380) ; Slave:mymaster
set data key_234:b'value_234'
Master:('10.0.0.22', 6380) ; Slave:mymaster
set data key_235:b'value_235'
Master:('10.0.0.22', 6380) ; Slave:mymaster
set data key_236:b'value_236'
Master:('10.0.0.22', 6380) ; Slave:mymaster
set data key_237:b'value_237'
Master:('10.0.0.22', 6380) ; Slave:mymaster
set data key_238:b'value_238'

##读程序

Master:('10.0.0.20', 6380) ; Slave:mymaster
get data key1:b'value1'
Master:('10.0.0.20', 6380) ; Slave:mymaster
get data key1:b'value1'
Master:('10.0.0.20', 6380) ; Slave:mymaster
get data key1:b'value1'
Master:('10.0.0.20', 6380) ; Slave:mymaster
get data key1:b'value1'
Master:('10.0.0.20', 6380) ; Slave:mymaster
get data key1:b'value1'
Master:('10.0.0.20', 6380) ; Slave:mymaster
get data key1:b'value1'
No master found for 'mymaster'
No master found for 'mymaster'
Master:('10.0.0.22', 6380) ; Slave:mymaster
get data key1:b'value1'
Master:('10.0.0.22', 6380) ; Slave:mymaster
get data key1:b'value1'
Master:('10.0.0.22', 6380) ; Slave:mymaster
get data key1:b'value1'
Master:('10.0.0.22', 6380) ; Slave:mymaster
get data key1:b'value1'
Master:('10.0.0.22', 6380) ; Slave:mymaster
get data key1:b'value1'
Master:('10.0.0.22', 6380) ; Slave:mymaster
get data key1:b'value1'

四、sentinel 运维

五、客户端连接Sentinel

1、客户端连接Sentinel工作原理

1、选举Sentinel

2、Sentinel通过MasterName获取Master节点信息

3、Sentinel发送Role指令确认Master节点信息

4、客户端订阅Sentinel频道,获取新的Master信息,并自动切换连接到新的Master

1.1、选举Sentinel

1.2、Sentinel通过MasterName获取Master节点信息

1.3、Sentinel发送Role指令确认Master节点信息

1.4、客户端订阅Sentinel频道,获取新的Master信息,并自动切换连接到新的Master

2、python连接Sentinel

 [root@Client-Ubuntu-1804-250:~]# apt install python3 python3-redis -y

[root@Client-Ubuntu-1804-250:~]# cat script/redis/redis_sentinel_newData.py 

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
#********************************************************************
#Author: janzen
#Date: 2023-04-18
#FileName: redis_sentinel_newData.py
#Description: The python3 script
#Copyright (C): 2023 All rights reserved
#********************************************************************
import redis
from redis.sentinel import Sentinel
import sys,time
key=sys.argv[1]
value=sys.argv[2]
num=1
redis_auth_pass='redis'
mastername='mymaster'
sentinel = Sentinel([
('10.0.0.20',26379),
('10.0.0.21',26379),
('10.0.0.22',26379)],
socket_timeout=0.5
)
while 1:
time.sleep(1)
try:
master = sentinel.discover_master(mastername)
slave = sentinel.discover_slave=(mastername)
print("Master:%s ; Slave:%s" % (master,slave))
master = sentinel.master_for(mastername,socket_timeout=0.5,password=redis_auth_pass,db=0)
w_ret=master.set(key+str(num),value+str(num)) slave = sentinel.slave_for(mastername,socket_timeout=0.5,password=redis_auth_pass,db=0)
r_ret=master.get(key+str(num))
print("set data %s:%s" % (key+str(num),r_ret))
except Exception as err:
print(err)
continue
num+=1

【Redis】Setninel 哨兵机制的相关教程结束。

《【Redis】Setninel 哨兵机制.doc》

下载本文的Word格式文档,以方便收藏与打印。