Redis集群之哨兵模式



前言

在主从集群架构中S节点宕机重启后可以找master节点同步数据,那Master节点宕机后怎么办呢? 为此,出现了Sentinel(哨兵),哨兵是Redis的高可用性解决方案。


一、什么是哨兵?

哨兵是一个分布式系统,用于对主从架构中的每台服务器进行监控,当Master出现故障时通过投票机制从Slave选择新的Master,并将所有的Slave连接到新的Master,当Slave出现故障时将其下线。为此哨兵有两个主要的职能一是监控, 二是选择,监控的是集群中每个节点的状态,选择的是当Master节点出现故障时重新选择出主节点。以此保证系统的可用性。除此之外,Redis哨兵还可以执行其他任务, 例如检测节点的配置变化、自动发现新的节点等。哨兵节点之间会进行通信,通过选举算法选出一个哨兵节点作为领导者(Leader),负责协调整个集群的状态和决策。

二、哨兵集群的作用

  1. 集群监控: 负责监控Redis的master和slave进程是否正常工作,即master存活检测master与slave运行情况检测
  2. 消息通知: 当被监控的Redis实例服务器出现问题时,向其他(哨兵间,客户端)发送通知
  3. 故障转移: 断开master与slave连接,选取一个slave作为master,将其他slave连接到新的master,并告知客户端地址。哨兵模式会监控所有的redis工作节点是否正常,当master出现问题的时候,因为其他节点与主节点失去联系,因此会投票,投票过半就认为这个master的确出现问题,然后会通知哨兵间,然后从slaves中选取一个作为新的master,通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器,当哨兵监测到Redis主机宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他服务器,修改配置文件,让slave换主机

注意: 哨兵也是一台redis服务器,只是不提供数据服务,通常redis哨兵模式配置的机器数量为单数

三、哨兵集群搭建

本文中我们使用Redis版本为5.0.0进行测试,在一台虚拟机上搭建哨兵模式的redis集群,使用不同的端口号来模拟不同的Redis实例,开启三台redis-server,一台主机两台从机。然后开启三台哨兵去监控主机。当主机宕机时,哨兵们会尝试与主机取得连接,当一定时间内未取得连接时,哨兵会判断该主机已经断线,选举新的主机。值得注意的是,只有大于一半的哨兵认为该主机断线才会选举新的主机。Redis端口对应如下:

ip+端口角色
127.0.0.1:7001主节点
127.0.0.1:7002从节点
127.0.0.1:7003从节点
127.0.0.1:17001哨兵节点1
127.0.0.1:17002哨兵节点2
127.0.0.1:17003哨兵节点3

哨兵架构图

3.1 搭建一主二从集群

修改redis的配置文件 redis.conf,搭建一主两从集群架构

  1. 创建路径 /data/soft/redis_5_0_0/master_slave,录

  [root@master master_slave]# mkdir -p /data/soft/redis_5_0_0/master_slave
  1. 创建不同实例运行目 master_7001 sentinel_17001 sentinel_17002 sentinel_17003 slave_7002 slave_7003
[root@master master_slave]# pwd
/data/soft/redis_5_0_0/master_slave
[root@master master_slave]# mkdir master_7001 sentinel_17001  sentinel_17002  sentinel_17003  slave_7002  slave_7003
[root@master master_slave]# ls
master_7001  sentinel_17001  sentinel_17002  sentinel_17003  slave_7002  slave_7003
[root@master master_slave]# 
  1. 修改主节点master的redis.conf配置文件, 本文已最精简配置文件进行测试
   # 编辑文件 redis.conf
  vim redis.conf
  # 清空redis.conf,写入如下内容
	port 7001
	daemonize yes
	pidfile "/data/soft/redis_5_0_0/master_slave/master_7001/redis_7001.pid"
	logfile "/data/soft/redis_5_0_0/master_slave/master_7001/redis.log"
	dir "/data/soft/redis_5_0_0/master_slave/master_7001"
	masterauth "123456"
	appendonly yes
	appendfilename "appendonly.aof"
	requirepass "123456"
  1. 以此类推修改slave从节点7002,7003
port 7002
daemonize yes
pidfile "/data/soft/redis_5_0_0/master_slave/slave_7002/redis.pid"
logfile "/data/soft/redis_5_0_0/master_slave/slave_7002/7002.log"
dir "/data/soft/redis_5_0_0/master_slave/slave_7002"
loglevel debug
replicaof 127.0.0.1 7001
masterauth "123456"
appendonly yes
appendfilename "appendonly.aof"
requirepass "123456"

5 启动主从集群

[root@master master_slave]# ls
master_7001  sentinel_17001  sentinel_17002  sentinel_17003  slave_7002  slave_7003
[root@master master_slave]#
[root@master master_slave]# /data/soft/redis_5_0_0/bin/redis-server /data/soft/redis_5_0_0/master_slave/master_7001/redis.conf
[root@master master_slave]# /data/soft/redis_5_0_0/bin/redis-server /data/soft/redis_5_0_0/master_slave/slave_7002/redis.conf
[root@master master_slave]# /data/soft/redis_5_0_0/bin/redis-server /data/soft/redis_5_0_0/master_slave/slave_7003/redis.conf

#查看redis进程
[root@master ~]# ps -axu | grep redis
root       3104  0.3  0.4 156536  7952 ?        Ssl  23:23   0:00 /data/soft/redis_5_0_0/bin/redis-server *:7001
root       3116  0.4  0.6 160632 11968 ?        Ssl  23:23   0:00 /data/soft/redis_5_0_0/bin/redis-server *:7002
root       3123  0.3  0.7 166776 14020 ?        Ssl  23:23   0:00 /data/soft/redis_5_0_0/bin/redis-server *:7003

  1. 查看主从集群
[root@master master_slave]# redis-cli 7001
127.0.0.1:7001> AUTH 123456
# 查看主从集群节点信息
127.0.0.1:7001> info Replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=7002,state=online,offset=414,lag=1
slave1:ip=127.0.0.1,port=7003,state=online,offset=414,lag=1
master_replid:13de6d8232092f894638a98eba163f5c87e1023a
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:414
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:414

3.2 修改哨兵配置文件并启动

修改哨兵配置文件,搭建三台哨兵监控一主两从集群

  1. 在目录先分别 sentinel_17001 sentinel_17002 sentinel_17003 创建配置文件 sentinel.conf
[root@master sentinel_17001]# pwd
/data/soft/redis_5_0_0/master_slave/sentinel_17001
[root@master sentinel_17001]# ls
redis-sentinel.pid  run.log  sentinel.conf
[root@master sentinel_17001]# vim sentinel.conf

  1. 在sentinel_17001目录的配置文件sentinel.conf 中分别添加如下内容,修改对应的路径及端口号
port 17001
daemonize yes
loglevel debug
pidfile "/data/soft/redis_5_0_0/master_slave/sentinel_17001/redis-sentinel.pid"
logfile "/data/soft/redis_5_0_0/master_slave/sentinel_17001/run.log"
dir "/data/soft/redis_5_0_0/master_slave/sentinel_17001"
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 127.0.0.1 7001 2
sentinel auth-pass mymaster 123456
  1. 在sentinel_17002目录的配置文件sentinel.conf 中分别添加如下内容,修改对应的路径及端口号
port 17002
daemonize yes
loglevel debug
pidfile "/data/soft/redis_5_0_0/master_slave/sentinel_17002/redis-sentinel.pid"
logfile "/data/soft/redis_5_0_0/master_slave/sentinel_17002/run.log"
dir "/data/soft/redis_5_0_0/master_slave/sentinel_17002"
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 127.0.0.1 7001 2
sentinel auth-pass mymaster 123456
sentinel config-epoch mymaster 0

  1. 在sentinel_17003目录的配置文件sentinel.conf 中分别添加如下内容,修改对应的路径及端口号
port 17003
daemonize yes
loglevel debug
pidfile "/data/soft/redis_5_0_0/master_slave/sentinel_17003/redis-sentinel.pid"
logfile "/data/soft/redis_5_0_0/master_slave/sentinel_17003/run.log"
dir "/data/soft/redis_5_0_0/master_slave/sentinel_17003"
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 127.0.0.1 7001 2
sentinel auth-pass mymaster 123456

  1. 依次启动哨兵集群
# 依次启动哨兵
[root@master slave_7002]# /data/soft/redis_5_0_0/bin/redis-sentinel /data/soft/redis_5_0_0/master_slave/sentinel_17001/sentinel.conf
[root@master slave_7002]# /data/soft/redis_5_0_0/bin/redis-sentinel /data/soft/redis_5_0_0/master_slave/sentinel_17002/sentinel.conf
[root@master slave_7002]# /data/soft/redis_5_0_0/bin/redis-sentinel /data/soft/redis_5_0_0/master_slave/sentinel_17003/sentinel.conf
# 查看进程 
[root@master slave_7002]# ps -aux | grep redis
root       3104  0.3  0.5 158584  9960 ?        Ssl  23:23   0:01 /data/soft/redis_5_0_0/bin/redis-server *:7001
root       3116  0.3  0.6 160632 11968 ?        Ssl  23:23   0:01 /data/soft/redis_5_0_0/bin/redis-server *:7002
root       3123  0.3  0.7 166776 14020 ?        Ssl  23:23   0:01 /data/soft/redis_5_0_0/bin/redis-server *:7003
root       3131  0.0  0.2  16188  5320 pts/1    S+   23:24   0:00 redis-cli -p 7001
root       3136  0.0  0.2  16188  5284 pts/2    S+   23:27   0:00 redis-cli -p 7001
root       3138  0.5  0.4 153976  7948 ?        Ssl  23:28   0:00 /data/soft/redis_5_0_0/bin/redis-sentinel *:17001 [sentinel]
root       3151  0.5  0.4 153976  7940 ?        Ssl  23:30   0:00 /data/soft/redis_5_0_0/bin/redis-sentinel *:17002 [sentinel]
root       3156  1.0  0.4 153976  7936 ?        Ssl  23:30   0:00 /data/soft/redis_5_0_0/bin/redis-sentinel *:17003 [sentinel]
root       3161  0.0  0.0 112824   980 pts/3    S+   23:30   0:00 grep --color=auto redis
[root@master slave_7002]#

  1. 分别查看哨兵启动的时的运行日志17001,17002,17003的运行日志run.log
    哨兵17001日志哨兵17002日志在这里插入图片描述

  2. redis客户端连接哨兵节点查看哨兵信息

127.0.0.1:17001> 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=127.0.0.1:7001,slaves=2,sentinels=3
127.0.0.1:17001>
# 连接哨兵17002查看状态信息
[root@master ~]# redis-cli -p 17002
127.0.0.1:17002> 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=127.0.0.1:7001,slaves=2,sentinels=3
127.0.0.1:17002>

3.3 故障转移

杀死主从集群中Master主节点模拟主节点宕机,实时查看日志,观察故障转移过程
以下图示分别为故障转移时的哨兵运行日志
17001故障转移日志
17003故障转移日志17002故障转移日志查看redis集群的配置文件,以下图示分别为从节点7003,7002的配置文件,从配置文件中可以发现,升级为主节点的配置文件中会去掉之前配置的同步主节点的ip,另一个从节点会将原来的复制ip换成新的
在这里插入图片描述去掉主节点同步的ip
从哨兵客户端查看主从节点状态
故障转移后的节点信息查看哨兵配置文件的变化,从下图配置中也可以看出监控的主节点也发生变化
哨兵配置文件节点变化## 3.4 节点发现
重启redis主节点,观察哨兵运行日志变化
在这里插入图片描述
在这里插入图片描述在这里插入图片描述


总结

以上就是我们搭建哨兵集群实现Redis主从架构高可用的流程,从实现高可用的过程中,可以发现,当主节点宕机,到从节点被重新选举为Master主节点过程中,Redis主从集群有短暂的不可写,这时服务如果有大量的写,则数据会丢失,因此哨兵模式可以保证集群的高可用,但是不能100%保证数据不丢失。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐