文章目录
- 1. 基本概念
- 1.1 主从复制的问题
- 1.2 高可用
- 1.3 Redis Sentinel 的高可用性
- 2. 安装和部署
- 2.1 部署拓扑结构
- 2.2 部署Redis数据节点
- 2.3 部署Sentinel节点
Redis的主从复制模式下,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点地址,对于很多应用场景这种故障处理的方式是无法接受的。可喜的是Redis从2.8开始正式提供了Redis Sentinel(哨兵)架构来解决这个问题,本文相对哨兵机制进行详细分析,主要内容如下:
- Redis Sentinel 的概念
- Redis Sentinel 安装部署
- Redis Sentinel API详解
- Redis Sentinel 客户端
- Redis Sentinel 实现原理
- Redis Sentinel 开发运维实践
1. 基本概念
首先我们对Redis Sentinel相关名词进行说明:
名词 | 逻辑结构 | 物理结构 |
主节点(master) | Redis主服务 / 数据库 | 一个独立的Redis进程 |
从节点(slave) | Redis从服务 / 数据库 | 一个独立的Redis进程 |
Redis 数据节点 | 主节点和从节点 | 主节点和从节点的进程 |
Sentinel 节点 | 监控Redis数据节点 | 一个独立的 Sentinel 进程 |
Sentinel 节点集合 | 若干 Sentinel 节点的抽象组合 | 若干 Sentinel 节点进程 |
Redis Sentinel | Redis 高可用实现方案 | Sentinel 节点集合和 Redis 数据节点进程 |
应用方 | 泛指一个或多个客户端 | 一个或者多个客户端进程或者线程 |
Redis Sentinel 是 Redis 的高可用实现方案,在实际的生产环境中,对提高整个系统的高可用性是非常有帮助的,这里会先回顾主从复制模式下故障处理可能产生的问题,而后引出高可用的概念,最后重点分析 Redis Sentinel 的基本架构、优势,以及是如何实现高可用的。
1.1 主从复制的问题
Redis的主从复制模式可以将主节点的数据改变同步给从节点,这样从节点就可以起到两个作用:第一,作为主节点的一个备份,一旦主节点出了故障不可达的情况,从节点可以作为后备“顶”上来,并且保证数据尽量不丢失(主从复制是最终一致性)。第二,从节点可以扩展主节点的读能力,一旦主节点不能支撑住大并发量的读操作,从节点可以在一定程度上帮助主节点分担读压力。
但是主从复制也带来了一下问题:
- 一旦主节点出现故障,需要手动将一个从节点晋升为主节点,同时需要修改应用方的主节点地址,还需要命令其他从节点去复制新的主节点,整个过程都需要人工干预。
- 主节点的写能力受到单机的限制。
- 主节点的存储能力受到单机的限制。
1.2 高可用
Redis主从复制模式下,一旦主节点出现了故障不可达,需要人工干预进行故障转移,无论对于Redis的应用方还是维护方都带来了很大的不便。对于应用方来说无法及时感知到主节点的变化,必然会造成一定的写数据丢失和读数据错误,甚至可能造成应用方服务不可用。对于Redis的运维方来说,整个故障转移的过程是需要人工来介入的,故障转移实时性和准确性上都无法得到保障,下面展示了一个1主2从的Redis主从复制模式下的主节点出现故障后,是如何进行故障转移的,过程如下:
1)如下图所示,主节点发生故障后,客户端(client)连接主节点失败,两个从节点与主节点连接失败造成复制中断。
2)如下图所示,如果主节点无法正常启动,需要选出一个从节点(slave-1),对其执行slaveof no one 命令使其成为新的主节点。
3)如下图所示,原来的从节点(slave-1)成为新的主节点后,更新应用方的主节点信息,重新启动应用方。
4)如下图所示,客户端命令另一个从节点(slave-2)去复制新的主节点(new-master)
5)如下图所示,待原来的主节点恢复后,让它去复制新的主节点。
上述处理过程就可以认为整个服务或者架构的设计不是高可用的,因为整个故障转移的过程需要人介入。考虑到这点,有些公司把上述流程自动化了,但是仍然存在如下问题:第一,判断节点不可达的机制是否健全和标准。第二,如果有多个从节点,怎样保证只有一个被晋升为主节点。第三,通知客户端新的主节点直接是否足够健壮。Redis Sentinel 正是用来解决这些问题。
1.3 Redis Sentinel 的高可用性
当主节点出现故障时,Redis Sentinel 能自动完成故障发现和故障转移,并通知应用方,从而实现真正的高可用。
Redis Sentinel 是一个分布式架构,其中包含若干个 Sentinel 节点和 Redis 数据节点,每个 Sentinel 节点会对数据节点和其余 Sentinel 节点进行监控,当它发现节点不可达时,会对节点做下线标识。如果标记的是主节点,它还会和其他 Sentinel 节点进行“协商”,当大多数 Sentinel 节点都认为主节点不可达时,它们会选举出一个 Sentinel 节点来完成自动故障转移的工作,同时会将这个变化实时通知给 Redis 应用方。整个过程完全是自动的,不需要人工来介入,所以这套方案很有效的解决了 Redis 的高可用问题。
Redis Sentinel 与 Redis 主从复制模式只是多了若干 Sentinel 节点,所以Redis Sentinel并没有针对Redis节点做了特殊处理。
从逻辑架构上看,Sentinel 节点集合会定期对所有节点进行监控,特别是对主节点的故障实现自动转移。
下面以1个主节点、2个从节点、3个Sentinel节点组成的 Redis Sentinel 为例子进行说明,拓扑结构如下图:
整个故障转移的处理逻辑有下面4个步骤:
- 主节点出现故障,此时两个从节点与主节点失去连接,主从复制失败。
- 每个Sentinel节点通过定期监控发现主节点出现了故障。
- 多个Sentinel节点对主节点的故障达成一致,选举出sentintl-3节点作为领导者负责故障转移。
- Sentinel领导者节点执行了故障转移,过程和上面高可用的流程是一样的,只是变成自动化完成的。
- 故障转移后整个Redis Sentinel 的拓扑结构如下图:
通过上面介绍的Redis Sentinel逻辑架构以及故障转移的处理,可以看出Redis Sentinel具有以下几个功能:
- 监控:Sentinel节点会定期检测Redis数据节点、其余Sentinel是否可达。
- 通知:Sentinel节点会将故障转移的结果通知给应用方。
- 主节点故障转移:实现从节点晋升为主节点并维护后序正确地主从关系。
- 配置提供者:在Redis Sentinel结构中,客户端在初始化的时候连接的是Sentinel节点集合,从中获取主节点信息。
同时看到,Redis Sentinel包含了若干Sentinel节点,这样做也带来了两个好处:
- 对于节点的故障判断是由多个Sentinel节点共同完成,这样可以有效地防止误判。
- Sentinel节点集合是由若干个Sentinel节点组成的,这样即使个别Sentinel节点不可用,整个Sentinel节点集合依然是健壮的。
但是Sentinel节点本身就是独立的Redis节点,只不过他们有一些特殊,它们不存储数据,只支持部分命令。下面我们介绍Redis Sentinel的部署过程。
2. 安装和部署
2.1 部署拓扑结构
下面将以3个Sentinel节点、1个主节点、2个从节点组成一个Redis Sentinel进行说明,拓扑结构如下:
2.2 部署Redis数据节点
1.启动主节点
[root@izuf6bsiti3f4kuichki8nz admin]# redis-server --port 6379 --daemonize yes
[root@izuf6bsiti3f4kuichki8nz admin]# redis-cli -h 127.0.0.1 -p 6379 ping
PONG
2.启动两个从节点
[root@izuf6bsiti3f4kuichki8nz admin]# redis-server --port 6380 --daemonize yes
--slaveof 127.0.0.1 6379
[root@izuf6bsiti3f4kuichki8nz admin]# redis-server --port 6381 --daemonize yes
--slaveof 127.0.0.1 6379
[root@izuf6bsiti3f4kuichki8nz admin]# redis-cli -h 127.0.0.1 -p 6380 ping
PONG
[root@izuf6bsiti3f4kuichki8nz admin]# redis-cli -h 127.0.0.1 -p 6381 ping
PONG
3.确定主从关系
主节点视角,它有两个从节点,分别是 127.0.0.1:6380 和 127.0.0.1:6381:
[root@izuf6bsiti3f4kuichki8nz admin]# redis-cli -h 127.0.0.1 -p 6379 info repli
cation
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=169,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=169,lag=1
master_repl_offset:169
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:168
从节点视角,它的主节点是 127.0.0.1:6379:
[root@izuf6bsiti3f4kuichki8nz admin]# redis-cli -h 127.0.0.1 -p 6380 info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:239
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
2.3 部署Sentinel节点