Redis哨兵模式高可用集群详解-创新互联
redis主从模式解决了数据备份和单例可能存在的性能问题,但是其也引入了新的问题,在redis的主从复制架构中,当主数据库遇到异常中断服务后,运维人员可以通过手动的方式选择一个从数据库来提升为主数据库,以使得系统能够继续提供服务。
为南谯等地区用户提供了全套网页设计制作服务,及南谯网站建设行业解决方案。主营业务为网站设计制作、做网站、南谯网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!然而整个操作过程相对麻烦且需要人工介入,难以实现自动化。为此,在redis2.8版本之后正式提供了sentinel(哨兵)架构来实现自动化的系统监控和故障恢复功能。
顾名思义,哨兵的作用就是对Redis的系统的运行情况的监控,它是一个独立进程。它的功能有2个:
- 监控主数据库(master)和从数据库(slave)是否运行正常;
- 主数据出现故障后自动选举出多个slave(如果有超过一个slave的话)中的一个来作为新的master,其它的slave节点会将它所追随的master的地址自动改为被提升为新master的地址;
Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。
2、Redis哨兵架构关于sentinel,需要明白几个概念,首先,每个sentinel节点其实就是一个redis实例,与主从节点不同的是sentinel节点作用是用于监控redis数据节点的,而sentinel节点可以有多个,多个sentinel集合则表示监控一组主从redis实例。
下面是多个哨兵的架构:
多个哨兵,不仅同时监控主从数据库,而且哨兵之间互为监控。
从图中可以看出,对于一组主从节点,sentinel只是在其外部额外添加的一组用于监控作用的redis实例。在主从节点和sentinel节点集合配置好之后,sentinel节点之间会相互发送消息,以检测其余sentinel节点是否正常工作,并且sentinel节点也会向主从节点发送消息,以检测监控的主从节点是否正常工作。
sentinel架构的主要作用是解决主从模式下主节点的故障转移工作的。这里如果主节点因为故障下线,那么某个sentinel节点发送检测消息给主节点时,如果在指定时间内收不到回复,那么该sentinel就会主观的判断该主节点已经下线,就会发送消息给其余的sentinel节点,询问其是否“认为”该主节点已下线,其余的sentinel收到消息后也会发送检测消息给主节点。
如果其认为该主节点已经下线,那么就会回复向其询问的sentinel节点,告知它也认为主节点已经下线,当该sentinel节点最先收到超过指定数目(配置文件中配置的数目和当前sentinel节点集合数的一半,这里两个数目的较大值)的sentinel节点回复说当前主节点已下线,那么其就会对主节点进行故障转移工作。
故障转移的基本思路是在slave节点中选取某个从节点,并向其发送“slaveof no one”(假设选取的从节点为172.16.213.18:6379),使其成为独立的节点(也就是新的主节点),然后sentinel向其余的从节点发送“172.16.213.18:6379”命令使它们重新成为新的主节点的从节点。
重新分配之后sentinel节点集合还会继续监控已经下线的主节点(假设为172.16.213.17:6379),如果其重新上线,那么sentinel会向其发送slaveof命令,使其成为新的主节点的从节点,这样故障转移工作就完成了。
3、哨兵模式工作原理在哨兵模式架构中,client端在首次访问Redis服务时,实际上访问的是哨兵(sentinel),sentinel会将自己监控的Redis实例的master节点信息返回给client端,client后续就会直接访问Redis的master节点,并不是每次都从哨兵处获取master节点的信息。
sentinel会实时监控所有的Redis实例是否可用,当监控到Redis的master节点发生故障后,会从剩余的slave节点中选举出一个作为新的master节点提供服务,并将新master节点的地址通知给client端,其他的slave节点会通过slaveof命令重新挂载到新的master节点下。当原来的master节点恢复后,也会作为slave节点挂在新的master节点下。
如下图:
在上图过程中,哨兵主要有两个重要作用:
- 第一:哨兵节点会以每秒一次的频率对每个 Redis 节点发送
PING
命令,并通过 Redis 节点的回复来判断其运行状态。 - 第二:当哨兵监测到主服务器发生故障时,会自动在从节点中选择一台将机器,并其提升为主服务器,然后使用 PubSub 发布订阅模式,通知其他的从节点,修改配置文件,跟随新的主服务器。
在实际生产情况中,Redis Sentinel 是集群的高可用的保障,为避免 Sentinel 发生意外,它一般是由 3~5 个节点组成,这样就算挂了个别节点,该集群仍然可以正常运转。
其结构图如下所示:
当sentinel集群部署时,各sentinel除了监控redis实例外,还会彼此进行监控,这就形成了多哨兵模式。
多哨兵模式工作过程:
1. 主观下线
主观下线,适用于主服务器和从服务器。如果在规定的时间内(配置参数:down-after-milliseconds),Sentinel 节点没有收到目标服务器的有效回复,则判定该服务器为“主观下线”。比如 Sentinel1 向主服务发送了PING
命令,在规定时间内没收到主服务器PONG
回复,则 Sentinel1 判定主服务器为“主观下线”。
2. 客观下线
客观下线,只适用于主服务器。 Sentinel1 发现主服务器出现了故障,它会通过相应的命令,询问其它 Sentinel 节点对主服务器的状态判断。如果超过半数以上的 Sentinel 节点认为主服务器 down 掉,则 Sentinel1 节点判定主服务为“客观下线”。
3. 投票选举
投票选举,所有 Sentinel 节点会通过投票机制,按照谁发现谁去处理的原则,选举 Sentinel1 为领头节点去做 Failover(故障转移)操作。Sentinel1 节点则按照一定的规则在所有从节点中选择一个最优的作为主服务器,然后通过发布订功能通知其余的从节点(slave)更改配置文件,跟随新上任的主服务器(master)。至此就完成了主从切换的操作。
总结:
要实现Redis节点的监控,sentinel首先要得到所有的Redis节点的信息。sentinel通过在配置文件中配置 sentinel monitor 选项来指定要监控的redis master节点的地址,然后在启动sentinel时,会创建与redis master节点的连接并向master节点发送一个info命令,master节点在收到info命令后,会将自身节点的信息和自己下面所有的slave节点的信息返回给sentinel,sentinel收到反馈后,会与新的slave节点创建连接,接下来就会每隔10秒钟向所有的redis节点发送info命令来获取最新的redis主从结构信息。
有了redis实例的主从信息后,sentinel就会以每秒钟一次的频率向所有redis实例发送一个PING命令,而且如果sentinel是集群部署的话,每个sentinel还会以同样的频率向其他sentinel实例发送PING命令。当redis实例和sentinel实例收到PING命令后,会向sentinel返回一个有效的回复:+PONG 、-LOADING 或者 -MASTERDOWN,若返回其他的回复,或者在指定时间内(sentinel down-after-milliseconds 选项配置)没有回复,那么sentinel认为实例的回复无效。如果实例在 sentinel down-after-milliseconds 时间内未返回过一次有效的回复,那该实例就会被sentinel标记为主观下线(Subjectively Down,简称 SDOWN,指的是单个 sentinel 实例对服务节点做出的下线判断)。
当redis master节点被足够数量(sentinel monitor 选项配置,其中的quorum即为指定的sentinel数量,下面会详细介绍相关参数)的sentinel标记为主观下线后,那么master节点就会被标记为客观下线(Objectively Down,简称 ODOWN,指的是多个 sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断。【一个 sentinel 可以通过向另一个 sentinel 发送 SENTINEL is-master-down-by-addr 命令来询问对方是否认为给定的服务器已下线】)。客观下线条件只适用于主服务器: 对于任何其他类型的 Redis 实例,sentinel 在将它们判断为下线前不需要进行协商, 所以slave服务器或者其他 sentinel 永远不会达到客观下线条件。
当redis master被标记为客观下线时,每个sentinel向其他slave节点发送info命令的频率由之前的10秒钟一次变为1秒钟一次。并且会通过raft算法在sentinel中选出一个leader,由leader节点完成redis的故障转移工作。
Sentinel 负责监控主从节点的“健康”状态。当主节点挂掉时,自动选择一个最优的从节点切换为主节点。客户端来连接 Redis 集群时,会首先连接 Sentinel,通过 Sentinel 来查询主节点的地址,然后再去连接主节点进行数据交互。当主节点发生故障时,客户端会重新向 Sentinel 要地址,Sentinel 会将最新的主节点地址告诉客户端。因此应用程序无需重启即可自动完成主从节点切换。
4、Redis sentinel选举redis-master规则如何从众多slave节点中选出一个作为master节点呢?redis文档中是这样描述sentinel选择新master的规则的。
Sentinel使用以下规则来选择新的主服务器:
- 在失效主服务器属下的从服务器当中,那些被标记为主观下线、已断线、或者最后一次回复PING命令的时间大于五秒钟的从服务器都会被淘汰。
- 在失效主服务器属下的从服务器当中,那些与失效主服务器连接断开的时长超过 down-affor 选项指定的时长十倍的从服务器都会被淘汰。
- 在经历了以上两轮淘汰之后剩下来的从服务器中,我们选出复制偏移量(replication offset)大的那个从服务器作为新的主服务器;如果复制偏移量不可用,或者从服务器的复制偏移量相同,那么带有最小运行ID的那个从服务器成为新的主服务器。
每个sentinel节点在本质上还是一个redis实例,只不过和redis数据节点不同的是,其主要作用是监控redis数据节点。
在redis安装目录下有个默认的文件sentinel.conf,这就是sentinel的配置文件。
1、sentinel.conf配置项下面对 Sentinel 配置文件的其他配置项做简单说明:
配置项 | 参数类型 | 说明 |
---|---|---|
dir | 文件目录 | 哨兵进程服务的文件存放目录,默认为 /tmp。 |
port | 端口号 | 启动哨兵的进程端口号,默认为 26379。 |
logfile | 文件名 | sentinel日志文件存放路径 |
sentinel monitor | 节点名 | sentinel监控的master节点的名称、地址和端口号,最后一个quorums表示至少需要多少个sentinel判定master节点故障才进行故障转移。一般配置为sentinel数量/2+1。 |
sentinel down-after-milliseconds | <服务名称><毫秒数(整数)> | 在指定的毫秒数内,若主节点没有应答哨兵的 PING 命令,此时哨兵认为服务器主观下线,默认时间为 30 秒。 |
sentinel parallel-syncs | <服务名称><服务器数(整数)> | 指定可以有多少个 Redis 服务同步新的主机,一般而言,这个数字越小同步时间越长,而越大,则对网络资源要求就越高。 |
sentinel failover-timeout | <服务名称><毫秒数(整数)> | 指定故障转移允许的毫秒数,若超过这个时间,就认为故障转移执行失败,默认为 3 分钟。 |
sentinel notification-script | <服务名称><脚本路径> | 脚本通知,配置当某一事件发生时所需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时发邮件通知相关人员。 |
sentinel auth-pass | <服务器名称><密码> | 若主服务器设置了密码,则哨兵必须也配置密码,否则哨兵无法对主从服务器进行监控。该密码与主服务器密码相同。 |
这里使用三台服务器,每台服务器上开启一个redis-server和redis-sentinel服务,redis-server端口为8000,redis-sentinel的端口为6800,修改默认端口是安全的第一步。
redis-server说明:
- 172.16.213.75:8000 主;
- 172.16.213.77:8000 从;
- 172.16.213.87:8000 从;
redis-sentinel说明:
- 172.16.213.75:6800;
- 172.16.213.77:6800;
- 172.16.213.78:6800;
首先下载安装redis:
[root@localhost redis]#wget http://download.redis.io/releases/redis-5.0.5.tar.gz
[root@localhost redis]#tar zxvf redis-5.0.5.tar.gz
[root@localhost redis]#cd redis-5.0.5.tar.gz
[root@localhost redis]#make
[root@localhost redis]#cd src
接着复制redis相关命令到/usr/sbin目录下,这样就可以直接执行这些命令,不用写全路径。
[root@localhost redis]#cp redis-cli redis-server redis-sentinel /usr/sbin/
在redis目录下有redis.conf和sentinel.conf配置文件示例,拷贝redis.conf、sentinel.conf 到/etc/目录,然后修改配置文件。
修改主redis-server配置文件内容如下:
port 8000
daemonize yes
bind 0.0.0.0
pidfile /var/run/redis-8000.pid
logfile /var/log/redis/redis-8000.log
修改从redis-server配置文件内容如下:
port 8000
daemonize yes
bind 0.0.0.0
pidfile /var/run/redis-8000.pid
logfile /var/log/redis/redis-8000.log
slaveof 172.16.213.75 8000 #从redis比主redis多这一行
slaveof指定主master的IP与端口号。
在三个节点依次启动redis-server:
[root@localhost redis]# redis-server /etc/redis.conf
三个redis服务启动完毕后,进入命令行,执行info replication查看当前主从配置。
4、搭建redis-sentinel集群redis-sentinel程序上面已经安装过了,这里只需要修改配置文件就可以了。
修改/etc/sentinel.conf,如果没有创建即可。
修改sentinel.conf配置文件内容如下:
daemonize yes
port 6800
logfile /var/log/redis/sentinel.log
pidfile /var/run/sentinel.pid
sentinel monitor redismaster 172.16.213.75 8000 2
sentinel down-after-milliseconds redismaster 5000
sentinel failover-timeout redismaster 15000
配置文件说明如下:
”port 6800”:sentinel监听端口,默认是26379,可以更改。
“sentinel monitor redismaster 172.16.213.75 8000 2” :
sentinel monitor
让 sentinel 去监控一个地址为 ip:port 的主服务器,这里的 master-name 可以自定义;
redismaster为自己起的集群的名字, 172.16.213.75是 master的ip 8000是master redis的端口号, 2 表示当有2个sentinel节点认为主节点出问题是,就可以发起failover,如果50%以上节点同意,就切换主节点成功。
down-after-milliseconds:表示在一定的时间内,没有PING通master节点,这个节点就认为master已经down,将其标记为主观下线。
failover-timeout
三个节点依次启动redis-sentinel:
方式一:
[root@localhost redis]# redis-sentinel /etc/sentinel.conf
方式二:
[root@localhost redis]# redis-server sentinel.conf --sentinel
三个redis-sentinel服务启动完毕后,连接任意sentinel服务可以获知当前主redis服务信息。
查看节点状态:
三、Redis哨兵集群测试 1、把主redis停掉下面模拟主服务意外宕机的情况,首先直接将主服务器的 Redis 服务终止,然后查看从服务器是否被提升为了主服务器。执行以下命令:
redis-cli -h 172.16.213.75 -p 8000 shutdown
查看日志:
显示master转换日志。
哨兵的配置文件 sentinel.conf 也发生了变化:
如果您想开启多个哨兵,只需配置要多个 sentinel.conf 文件即可,一个配置文件开启一个。
2、查看redis-sentinel的监控状态登录redis查看节点状态:
此时会发现,172.16.213.77或78这台redis-server提升为主库。
至此,redis的高可用方案已经搭建完成。
3、客户端程序连接问题客户端程序(如PHP程序)连接redis时需要ip和port,但redis-server进行故障转移时,主redis是变化的,所以ip地址也是变化的。客户端程序如何感知当前主redis的ip地址和端口呢?可以使用vip方案来解决这个问题。
VIP方案是,redis系统对外始终是同一ip地址,当redis进行故障转移时,需要做的是将VIP从之前的redis服务器漂移到现在新的主redis服务器上。
比如:当前redis系统中主redis的ip地址是172.16.213.75,那么VIP(172.16.213.229)指向172.16.213.75,客户端程序用VIP(172.16.213.229)地址连接redis,实际上连接的就是当前主redis,这样就避免了向sentinel发送请求。
当主redis宕机,进行故障转移时,如果172.16.213.77这台服务器上的redis提升为主,这时VIP(172.16.213.229)就会添加到172.16.213.77主机上,这样客户端程序不需要修改任何代码,仍然连接vip地址,其实连接的就是目前新的master节点(就是172.16.213.77这台新主redis)。
四、漂移VIP实现Redis集群无缝切换那么现在的问题是,如何在进行redis故障转移时,将VIP漂移到新的主redis服务器上。
这里可以使用redis sentinel的一个参数client-reconfig-script,这个参数配置执行脚本,sentinel在做failover的时候会执行这个脚本,并且传递6个参数
如何利用这个参数呢,只需在sentinel.conf中添加如下内容即可:
sentinel client-reconfig-script redismaster /data/redis/notifyvip.sh
修改三个服务器的redis-sentinel配置文件/etc/sentinel.conf,增加上面一行。
然后在/data/redis目录下创建notifyvip.sh脚本文件,这个脚本做VIP漂移操作,内容如下:
# notifyvip.sh脚本内容
#!/bin/bash
MASTER_IP=$6 #第六个参数是新主redis的ip地址
LOCAL_IP='172.16.213.75' #其他两个服务器上为172.16.213.77,172.16.213.78
VIP='172.16.213.229'
NETMASK='24'
INTERFACE='em2'
if [[ "${MASTER_IP}" == "${LOCAL_IP}" ]];then
/sbin/ip addr add ${VIP}/${NETMASK} dev ${INTERFACE} #将VIP绑定到该服务器上
/sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
exit 0
else
/sbin/ip addr del ${VIP}/${NETMASK} dev ${INTERFACE} #将VIP从该服务器上删除
exit 0
fi
exit 1 #如果返回1,sentinel会一直执行这个脚本
现在当前主redis是172.16.213.75,仅第一次需要手动绑定VIP到该服务器上。
/sbin/ip addr add 172.16.213.229/24 dev em2
/sbin/arping -q -c 3 -A 172.16.213.229 -I em2
然后,去另一个服务器上通过VIP地址连接redis-server和redis-sentinel。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网页题目:Redis哨兵模式高可用集群详解-创新互联
URL分享:http://hbruida.cn/article/pjddh.html