Redis 哨兵模式

前面章节介绍了 Redis 的主从复制,主从复制有一个致命的问题,即当 Master 服务器宕掉时,不会自动切换 Master,需要人为干预。鉴于这个问题,Redis 提供了哨兵功能。

哨兵是 Redis 集群架构中非常重要的一个组件,哨兵的出现主要是解决了主从复制出现故障时需要人为干预的问题,哨兵实现了自动化的故障恢复。如下图:

上图中,Sentinel(哨兵)分别监听了 Master、Slave 节点,当 Master 宕机后哨兵实现了自动化的故障恢复,即重新选择新的 Master。

注意:在配置哨兵模式之前,需要提前配置好 Master-Slave 主从复制模式,如不知道怎样配置,请参考“Redis 主从复制”。

哨兵模式优缺点

优点

哨兵模式是基于主从模式的,解决了主从模式中 Master 服务器故障不可以自动切换故障的问题。

缺点

(1)它是一种中心化的集群实现方案,始终只有一个 Redis 主机来接收和处理写请求,写操作受单机瓶颈影响。

(2)集群里所有节点保存的都是全量数据,浪费内存空间,没有真正实现分布式存储。数据量过大时,主从同步严重影响 Master 服务器的性能。

(3)Master 宕机后,有一段时间 Redis 是不可写的。因为投票选举结束之前,谁也不知道主机和从机是谁,并且 Redis 也会开启保护机制,禁止写操作,直到选举出了新的 Master。

哨兵模式主要功能

(1)集群监控:负责监控 Redis Master 和 Slave 进程是否正常工作

(2)消息通知:如果某个 Redis 实例有故障,那么哨兵负责发送消息作为报警通知给管理员

(3)故障转移:如果 Master 服务器挂掉了,会自动转移到 Slave 服务器上

(4)配置中心:如果故障转移发生了,通知 Client 客户端新的 Master 地址

哨兵监控节点过程

下面将介绍哨兵模式中哨兵是怎样监控各个节点的,具体流程如下:

(1)Master 节点的信息配置在哨兵(Sentinel)的配置文件中

(2)哨兵节点会和配置的 Master 节点建立起两条连接命令连接和订阅连接

(3)哨兵会通过命令连接,每 10s 发送一次 INFO 命令,通过 INFO 命令,主节点会返回自己的 run_id 和自己的从节点信息。

(4)哨兵会对这些 Slave 节点也建立两条连接命令连接和订阅连接。

(5)哨兵通过命令连接向 Slave 节点发送 INFO 命令,获取到他的一些信息,如 run_id(Redis 服务器 id)、role(职能)、从服务器的复制偏移量 offset以及其他信息

(6)通过命令连接向服务器的 sentinel:hello 频道发送一条消息,内容包括自己的 ip、端口、run_id、配置(后续投票的时候会用到)等。

(7)通过订阅连接对服务器的 sentinel:hello 频道做了监听,所以所有的向该频道发送的哨兵的消息都能被接受到。

(8)解析监听到的消息,进行分析提取,就可以知道还有那些别的哨兵服务节点也在监听这些主从节点了,更新结构体将这些哨兵节点记录下来。

(9)向观察到的其他的哨兵节点建立命令连接→没有订阅连接。

哨兵模式下的故障迁移

主观下线

哨兵 (Sentinel) 节点会每秒一次的频率向建立了命令连接的实例发送 PING 命令,如果在 down-after--milliseconds 毫秒内没有做出有效响应包括 (PONG/ LOADINC/MASTERDOWN) 以外的响应,哨兵就会将该实例在本结构体中的状态标记为 SRI_S_DOWN 主观下线。

客观下线

当一个哨兵节点发现主节点处于主观下线状态,会向其他的哨兵节点发出询问,该节点是不是已经主观下线了。如果超过配置参数 quorum 个节点认为是主观下线时,该哨兵节点就会将自己维护的结构体中该主节点标记为 SRIO  DOWN 客观下线询问命令 SENTINEL is-master-down-by-addr。

master选举

在认为主节点客观下线的情况下,哨兵节点节点间会发起一 次选举,命令为:SENTINEL is-master-down-by-addr。

只是 runid 这次会将自己的 runid 带进去, 希望接受者将自己设置为主节点。如果超过半数以上的节点返回将该节点标记为 leacer 的情况下,会有该 leader 对故障进行迁移。

故障转移

在从节点中挑选出新的主节点

(1)通讯正常

(2)优先级排序

(3)优先级相同时选择 offset 最大的

将该节点设置成新的主节点 SLAVEOFnoone,并确保在后续的 ING0 命令时该节点返回状态为 master,将其他的从节点设置成从新的主节点复制,SLAVE0F 命令将旧的主节点变成新的主节点的从节点。

哨兵模式配置

该实例将在单台 Windows 环境服务器下演示 Redis 哨兵模式的配置,服务节点信息如下:

Master   127.0.0.1:6379
Slave1   127.0.0.1:6378
Slave2   127.0.0.1:6377

注意:

(1)搭建 Redis 哨兵模式时需先搭建 Redis 主从复制(这是为什么呢?因为哨兵是用来解决 Redis 主从复制中 Master 宕掉后,自动选择一个 Slave 作为新的 Master)。

(2)哨兵模式配置需在一个单独的 sentinel.conf 配置文件中进行配置。

(3)通常情况下,一个 Redis 服务(不管是 Master 还是 Slave)均启动一个哨兵,即多哨兵。

下面将通过配置一个哨兵来简单介绍怎样为 Redis 主从复制配置哨兵。

哨兵的配置

注意,你可以选择一个单独的 Redis 实例来运行哨兵服务,当然也可以使用 Master 或 Slave 实例来运行哨兵服务。

默认情况下 Redis 没有提供哨兵的配置文件 sentinel.conf,因此,需要我们自己在 Redis 主目录,即 redis.conf 配置文件所在的目录下面创建 sentinel.conf 配置文件,配置文件可以从 Redis 源码包的 src 目录中找到默认的 sentinel.conf 文件,修改的配置内容如下:

# 是否开启保护模式,这里选择不开启
protected-mode no

# 设置哨兵的端口
port 26379

# 设置哨兵服务是否后台运行,这里选择不后台运行,便于我们观察启动日志
# 正式环境,建议设置为 yes,后台启动
daemonize no

# Sentinel去监视一个名为 mymaster 的主 redis 实例
# 这个主实例的 IP 地址为 127.0.0.1,端口号为6379
# 而将这个主实例判断为失效至少需要 2 个 Sentinel 进程的同意
# 只要同意 Sentinel 的数量不达标,自动 failover 就不会执行
sentinel monitor mymaster 127.0.0.1 6379 1

# 指定了 Sentinel 认为 Redis 实例已经失效所需的毫秒数
# 当实例超过该时间没有返回 PING,或者直接返回错误
# 那么 Sentinel 将这个实例标记为主观下线。
# 只有一个 Sentinel 进程将实例标记为主观下线并不一定会引起实例的自动故障迁移
# 只有在足够数量的 Sentinel 都将一个实例标记为主观下线之后
# 实例才会被标记为客观下线,这时自动故障迁移才会执行
sentinel down-after-milliseconds mymaster 5000

# 设置连接 master 和 slave 时的密码,注意 sentinel 不能分别为 master
# 和 slave 设置不同的密码,因此 master 和 slave 的密码应该设置相同
sentinel auth-pass mymaster aaaaaa

# 指定了在执行故障转移时,最多可以有多少个从 Redis 实例在同步新的主实例
# 在 Redis 从(Slave)实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长
sentinel config-epoch mymaster 4

运行哨兵模式

运行哨兵模式和运行 Redis 服务有点不一样,需要通过 --sentinel 选项来启动哨兵。命令如下:

redis-server.exe sentinel.conf --sentinel

执行上面命令将启动哨兵服务,日志如下:

[49660] 04 Apr 13:06:39.987 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
[49660] 04 Apr 13:06:39.988 # Redis version=5.0.14.1, bits=64, commit=ec77f72d, modified=0, pid=49660, just started
[49660] 04 Apr 13:06:39.988 # Configuration loaded
               _._
          _.-``__ ''-._
     _.-``    `.  `_.  ''-._           Redis 5.0.14.1 (ec77f72d/0) 64 bit
 .-`` .-```.  ```\/    _.,_ ''-._
(    '      ,       .-`  | `,    )     Running in sentinel mode
|`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
|    `-._   `._    /     _.-'    |     PID: 49660
 `-._    `-._  `-./  _.-'    _.-'
|`-._`-._    `-.__.-'    _.-'_.-'|
|    `-._`-._        _.-'_.-'    |           http://redis.io
 `-._    `-._`-.__.-'_.-'    _.-'
|`-._`-._    `-.__.-'    _.-'_.-'|
|    `-._`-._        _.-'_.-'    |
 `-._    `-._`-.__.-'_.-'    _.-'
     `-._    `-.__.-'    _.-'
         `-._        _.-'
             `-.__.-'

[49660] 04 Apr 13:06:39.992 # Sentinel ID is 19e18f6594d97e540e075ca27bd73708911ad102
[49660] 04 Apr 13:06:39.992 # +monitor master mymaster 127.0.0.1 6379 quorum 1

哨兵模式验证

查看哨兵信息

通过 redis-cli 命令连接到哨兵服务,运行 info sentinel 命令查看哨兵服务信息,命令如下:

C:\Users\Administrator>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=sdown,address=127.0.0.1:6379,slaves=2,sentinels=1

验证哨兵选举Master

验证详细步骤如下:

(1)先查看 Redis 主从复制的服务信息,如下:

C:\Users\Administrator>redis-cli
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6378,state=online,offset=54297,lag=1
slave1:ip=127.0.0.1,port=6377,state=online,offset=54297,lag=1
master_replid:71696462f65b3c97ab4f58dff865824841a0352f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:54297
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:54297

(2)关闭 Master 服务

(3)观察哨兵服务的输出日志,哨兵服务多出如下日志:

[49660] 04 Apr 13:07:48.967 # +sdown master mymaster 127.0.0.1 6379
[49660] 04 Apr 13:07:48.967 # +odown master mymaster 127.0.0.1 6379 #quorum 1/1
[49660] 04 Apr 13:07:48.967 # +new-epoch 5
[49660] 04 Apr 13:07:48.967 # +try-failover master mymaster 127.0.0.1 6379
[49660] 04 Apr 13:07:48.969 # +vote-for-leader 19e18f6594d97e540e075ca27bd73708911ad102 5
[49660] 04 Apr 13:07:48.969 # +elected-leader master mymaster 127.0.0.1 6379
[49660] 04 Apr 13:07:48.969 # +failover-state-select-slave master mymaster 127.0.0.1 6379
[49660] 04 Apr 13:07:49.044 # +selected-slave slave 127.0.0.1:6377 127.0.0.1 6377 @ mymaster 127.0.0.1 6379
[49660] 04 Apr 13:07:49.044 * +failover-state-send-slaveof-noone slave 127.0.0.1:6377 127.0.0.1 6377 @ mymaster 127.0.0.1 6379
[49660] 04 Apr 13:07:49.107 * +failover-state-wait-promotion slave 127.0.0.1:6377 127.0.0.1 6377 @ mymaster 127.0.0.1 6379
[49660] 04 Apr 13:07:49.990 # +promoted-slave slave 127.0.0.1:6377 127.0.0.1 6377 @ mymaster 127.0.0.1 6379
[49660] 04 Apr 13:07:49.990 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6379
[49660] 04 Apr 13:07:50.066 * +slave-reconf-sent slave 127.0.0.1:6378 127.0.0.1 6378 @ mymaster 127.0.0.1 6379
[49660] 04 Apr 13:07:51.045 * +slave-reconf-inprog slave 127.0.0.1:6378 127.0.0.1 6378 @ mymaster 127.0.0.1 6379
[49660] 04 Apr 13:07:51.045 * +slave-reconf-done slave 127.0.0.1:6378 127.0.0.1 6378 @ mymaster 127.0.0.1 6379
[49660] 04 Apr 13:07:51.108 # +failover-end master mymaster 127.0.0.1 6379
[49660] 04 Apr 13:07:51.108 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6377

通过上面日志信息可知,哨兵服务选择 6377(即Slave2)服务为新的 Master。

(4)再次连接 6377 服务,查看主从复制服务信息,如下:

C:\Users\Administrator>redis-cli -p 6377
127.0.0.1:6377> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6378,state=online,offset=10253,lag=1
master_replid:1e7e3125a215749c8b26b3405a9f7de3cabfe270
master_replid2:ccb61d5c613f6abb655b38f0aa9d2684403a6c49
master_repl_offset:10253
second_repl_offset:5226
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:10253

上面日志表面,当前服务(6377)为 Master 角色,拥有一个 Slave 节点。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号