redis 命令别名_【死磕 Redis】 哨兵(一):部署哨兵架构

Redis Sentinel 提供监控、自动故障转移、配置提供和通知功能,确保高可用性。本文详述哨兵系统的部署,包括主从节点和哨兵节点的配置,以及故障转移的自动化过程,展示了哨兵如何在主节点故障时,通过投票选出新的主节点并通知客户端,实现无缝切换。
摘要由CSDN通过智能技术生成

在介绍 Redis 主从复制的时候,提到了相比于单机的 Redis 架构,主从复制架构具有如下优势:

  • 保证数据安全性。从节点作为主节点备份,一旦主节点不可用,从节点可以顶上去,保证了数据尽量不被丢失

  • 提高读能力。主从读写分离,横向扩展的系统的读负载

  • Redis 高可用的基础

但是主从复制架构有一个非常致命的问题,那就是一旦主节点由于故障不可用时,需要手动将一个从节点晋升为主节点,需要将其他节点的主节点替换为新的主节点,同时还需要修改应用的主节点地址,如果应用方没使用配置中心则还需要重启服务,整个过程都需要人工干预,而且工程量也不小,这是一个无法接受的问题。幸好,在 Redis 2.8 提供比较完善的解决方案:Redis Sentinel。Redis Sentinel 是一个能够自动完成故障发现和故障转移并通知应用方,从而实现真正的高可用的分布式架构。下面是Redis官方文档对于哨兵功能的描述:

  • 监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。

  • 自动故障转移(Automatic failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。

  • 配置提供者(Configuration provider):客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。

  • 通知(Notification):哨兵可以将故障转移的结果发送给客户端。

监控和自动故障转移使得 Sentinel 能够完成主节点故障发现和自动转移,配置提供者和通知则是实现通知客户端主节点变更的关键。

架构

fa713caf0f8cc329f4b594d5cc5b60b0.png

典型的哨兵架构图如上图所示,它主要包括两个部分:哨兵节点和数据节点。

  • 哨兵节点:哨兵系统由若干个哨兵节点组成。其实哨兵节点就是一个特殊的 Redis 节点,只不过它是不存储数据的和仅支持部分命令

  • 数据节点:由主节点和从节点组成的数据节点。

部署

这部分将部署一个简单的哨兵系统,包含 1 一个主节点,2 个从节点和 3 个哨兵节点,配置如下:

节点IP端口
主节点127.0.0.16379
从节点 1127.0.0.16380
从节点 2127.0.0.16381
哨兵节点 1127.0.0.126379
哨兵节点 2127.0.0.126380
哨兵节点 3127.0.0.126381

哨兵部署

上面介绍了典型的哨兵架构包括了哨兵节点和数据节点,所以这里我们分为两步部署。

部署 Redis 数据节点

部署 Redis 数据节点其实就是部署主从架构,按照我们上面的要求是一主两从的架构。

一主

6379 是我们的主节点,配置如下:

--redis-6379.conf

port 6379

daemonize yes

pidfile "/var/run/redis_6379.pid"

logfile "/Users/chenssy/Documents/workSpace/environment/redis-5.0.3/6379/redis.log"

dir "/Users/chenssy/Documents/workSpace/environment/redis-5.0.3/6379"

然后启动主节点即可。redis-server../6379/redis-6379.conf

两从

两个从节点的配置和主节点基本一致,如下:

--redis-6380.conf

port 6380

daemonize yes

pidfile "/var/run/redis_6380.pid"

logfile "/Users/chenssy/Documents/workSpace/environment/redis-5.0.3/6380/redis.log"

dir "/Users/chenssy/Documents/workSpace/environment/redis-5.0.3/6380"

slaveof 127.0.0.1 6379

启动 6380 和 6381 两个节点,这时他们与 6379 已经建立了主从关系,从 6379 视角看,它有两个从节点 6380、6381,如下:

394a141b19fee36b57ff4a49978a6861.png

此时,拓扑结构图如下:

71f03c6395fe68dfe6177138ea6159d6.png

部署 Sentinel 节点

3 个 Sentinel 节点的部署方式完全一致,仅仅只是端口不同,下面只演示 26379 节点的部署。

配置

-- redis-26379.conf

port 26379

daemonize yes

pidfile "/var/run/redis_26379.pid"

logfile "/Users/chenssy/Documents/workSpace/environment/redis-5.0.3/26379/redis.log"

dir "/Users/chenssy/Documents/workSpace/environment/redis-5.0.3/26379"

sentinel monitor mymaster 127.0.0.1 6379 2

相比数据节点的配置仅多了一个配置项,所以这里我们的配置部分尽量简化,更多配置会在后面介绍。

sentinel monitor mymaster127.0.0.163792,表示的意义是该哨兵节点监控 127.0.0.1:6379 这个主节点,mymaster 是主节点的别名,最后的 2 的含义是至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移。

启动

哨兵节点的启动有两种方式:

redis-sentinel ../26379/redis-26379.conf

redis-server ../26379/redis-26379.conf --sentinel

启动的效果完全一致。

按照上述配置和启动 26380 和 26381 哨兵节点。

验证

按照上述过程,整个哨兵架构已经搭建完毕了,我们可以通过 info 命令来进行验证。如下:

6af654e1cd428e41bdc08232cbac33bf.png

通过上图,我们可以看出 26379 哨兵节点已经监控了 mymaster 的主节点,地址为 127.0.0.1:6379,并且发现了两个从节点和其余 2 个哨兵节点。

此时,如果我们再看下哨兵节点的配置文件,会发现末尾多了几个配置,如下:

a8026d1f63523dd7df8d23d7e62d7101.png

known-slave 和 known-sentinel 显示哨兵已经发现了从节点和其他哨兵;带有 epoch 的参数与配置纪元有关(配置纪元是一个从0开始的计数器,每进行一次领导者哨兵选举,都会+1;领导者哨兵选举是故障转移阶段的一个操作,在后文原理部分会介绍)

至此,整个哨兵架构已经搭建完毕了,整体拓扑结构图如下:

b6169d68a7cb41056d5bbf5348e3b8cf.png

故障转移演示

我们先来回想下在主从架构模式下,当主节点发生故障后,我们是如何手动恢复的呢?

  1. 我们选定一个从节点对其执行 slaveofnoone 命令,使其变成一个新的主节点

  2. 将其他从节点变成新主节点的从节点,执行命令 slaveof新IP新port

  3. 更新客户端的 Redis 连接信息,重启应用

  4. 启动发送了故障的主节点,执行 slaveof新IP新port 使其变成新主节点的从节点

上面的过程都需要人工干预,同时也会存在几个问题,比如我们是如何发送主节点故障了呢?判断主节点故障的机制是否完善?选择从节点的机制是否完善呢?等等一系列的问题,所以对于这种方案在生产环境下我们肯定是不可能接受的,那么如何解决呢?Redis Sentinel 就是解决这些问题的方案,下面就 Redis Sentinel 是如何实现故障转移的流程做一个简要的说明。

  1. 主节点出现故障导致不可用,这时从节点和客户端都与其失去联系

  2. Sentinel 节点通过定时监控发现主节点出现了故障,判断其不可用(可能是某个节点主观认为不可用),当大多数 Sentinel 对主节点的故障判断达成一致时,就会选举一个 Sentine-l 节点作为领导者来负责故障转移

  3. Sentinel-1 通过一定规则选择其中一个从节点作为新的主节点,然后整个过程就和上面手动恢复一致了,只不过它是又 sentinel-1 来自动完成的。

故障转移后,上图架构变成了下图所示:

56e34663fa2f21de71c340f7500ac229.png

下面就主节点 6379 发生故障时,哨兵的监控和自动故障转移。

  • (1) 首先利用 kill 命令将 6379 进程杀掉

杀掉 6379 这个主节点后,6380、6381 两个从节点会连接不上 master 主节点,打印如下日志:

12920:S 05 Jun 2019 17:55:06.377 # Connection with master lost.

12920:S 05 Jun 2019 17:55:06.377 * Caching the disconnected master state.

12920:S 05 Jun 2019 17:55:06.820 * Connecting to MASTER 127.0.0.1:6379

12920:S 05 Jun 2019 17:55:06.820 * MASTER REPLICA sync started

12920:S 05 Jun 2019 17:55:06.821 # Error condition on socket for SYNC: Connection refused

  • (2) 等待一段时间,因为哨兵发现主节点故障和转移故障是需要时间的。等待一段时间后,执行 redis-cli-p26379infoSentinel,会发现 address 发生了变化,如下图:

178e4dc395ce8a1635dc78fd75fbfcc2.png

address 变成了 127.0.0.1:6381 ,所以这里 6381 已经晋升为主节点了。节点 6381 的会出现如下日志:

12932:M 05 Jun 2019 17:55:36.774 # Setting secondary replication ID to 8ae16004358ae685a7424c762a05896d25502cd0, valid up to offset: 274648. New replication ID is 819f25bcda084be13f0a030d1008bb282d8d9095

12932:M 05 Jun 2019 17:55:36.774 * Discarding previously cached master state.

12932:M 05 Jun 2019 17:55:36.774 * MASTER MODE enabled (user request from 'id=6 addr=127.0.0.1:64902 fd=10 name=sentinel-97fb37fc-cmd age=1424 idle=0 flags=x db=0 sub=0 psub=0 multi=3 qbuf=140 qbuf-free=32628 obl=36 oll=0 omem=0 events=r cmd=exec')

12932:M 05 Jun 2019 17:55:36.777 # CONFIG REWRITE executed with success.

节点 6381 的日志如下:

12920:S 05 Jun 2019 17:55:37.707 * REPLICAOF 127.0.0.1:6381 enabled (user request from 'id=6 addr=127.0.0.1:64904 fd=10 name=sentinel-97fb37fc-cmd age=1425 idle=0 flags=x db=0 sub=0 psub=0 multi=3 qbuf=281 qbuf-free=32487 obl=36 oll=0 omem=0 events=r cmd=exec')

12920:S 05 Jun 2019 17:55:37.708 # CONFIG REWRITE executed with success.

12920:S 05 Jun 2019 17:55:38.105 * Connecting to MASTER 127.0.0.1:6381

12920:S 05 Jun 2019 17:55:38.105 * MASTER REPLICA sync started

12920:S 05 Jun 2019 17:55:38.106 * Non blocking connect for SYNC fired the event.

12920:S 05 Jun 2019 17:55:38.106 * Master replied to PING, replication can continue...

12920:S 05 Jun 2019 17:55:38.106 * Trying a partial resynchronization (request 8ae16004358ae685a7424c762a05896d25502cd0:274648).

12920:S 05 Jun 2019 17:55:38.107 * Successful partial resynchronization with master.

12920:S 05 Jun 2019 17:55:38.107 # Master replication ID changed to 819f25bcda084be13f0a030d1008bb282d8d9095

从这个日志我们可以看到如下几个信息:6380 变成了 6381 的从节点,向节点 6381 发送复制请求。

主节点 6381 的日志如下:

12932:M 05 Jun 2019 17:55:38.106 * Replica 127.0.0.1:6380 asks for synchronization

12932:M 05 Jun 2019 17:55:38.107 * Partial resynchronization request from 127.0.0.1:6380 accepted. Sending 289 bytes of backlog starting from offset 274648.

日志显示 6381 发送 6380 的数据量有 289 bytes。到这里了,如果小伙伴们对主从复制还记忆犹新的话,一定会有一个疑问:为什么 6380 与 6381 之间不是进行全量复制而是部分复制?,因为我们知道 6380 发送 psync runid offset 命令进行复制时,这里的 runid 照理来说应该是 6379 的 runid,与 6381 的 runid 不相等,所以应该是进行全量复制而不是部分复制?关于这点,小编也是莫名其妙,请教了一些人,最后在一位大佬的帮助下得到了解答,那就是 Redis 4.0 以后的新特性 PSYNC2,它解决了因实例重启和主实例故障切换带来的全量复制的问题,这个小编后面写一篇文章来分析下,敬请期待。

通过上面的日志,我们就已经知道了数据节点是如何完成故障转移的,下面我们再分析哨兵节点的日志。

26379 的日志:

12951:X 05 Jun 2019 17:55:36.483 # +sdown master mymaster 127.0.0.1 6379

12951:X 05 Jun 2019 17:55:36.534 # +new-epoch 1

12951:X 05 Jun 2019 17:55:36.536 # +vote-for-leader 97fb37fc855e86a02eb446194cd4b1af6e2eef0c 1

26380 的日志:

12960:X 05 Jun 2019 17:55:36.467 # +sdown master mymaster 127.0.0.1 6379

12960:X 05 Jun 2019 17:55:36.530 # +odown master mymaster 127.0.0.1 6379 #quorum 2/2

12960:X 05 Jun 2019 17:55:36.530 # +new-epoch 1

26379 的日志:

12969:X 05 Jun 2019 17:55:36.402 # +sdown master mymaster 127.0.0.1 6379

12969:X 05 Jun 2019 17:55:36.534 # +new-epoch 1

12969:X 05 Jun 2019 17:55:36.536 # +vote-for-leader 97fb37fc855e86a02eb446194cd4b1af6e2eef0c 1

从这三个哨兵节点可以看出,三个哨兵节点都发现了主节点 6379 下线了,他们更新了自己的配置纪元(new-epoch),同时 26379、26379 投票给 26380,所以 26380 负责故障的转移工作,同时从 26380 的日志 +odown master mymaster127.0.0.16379#quorum 2/2 得知主节点 6379 已经达到了客观下线的条件了,其他两个陆续也会完成 6379 主节点的下线,如下:

--26379

12951:X 05 Jun 2019 17:55:36.552 # +odown master mymaster 127.0.0.1 6379 #quorum 3/2

--26381

12969:X 05 Jun 2019 17:55:37.473 # +odown master mymaster 127.0.0.1 6379 #quorum 3/2

按照日志的时间节点,我们可以得出 26380 最先完成客观下线,如下:

节点下线时间
2637917:55:36.552 # +odown master mymaster 127.0.0.1 6379 #quorum 3/2
2638017:55:36.530 # +odown master mymaster 127.0.0.1 6379 #quorum 2/2
2638117:55:37.473 # +odown master mymaster 127.0.0.1 6379 #quorum 3/2

继续看 26380 的日志:

12960:X 05 Jun 2019 17:55:36.530 # +try-failover master mymaster 127.0.0.1 6379

12960:X 05 Jun 2019 17:55:36.532 # +vote-for-leader 97fb37fc855e86a02eb446194cd4b1af6e2eef0c 1

12960:X 05 Jun 2019 17:55:36.536 # 0a16a0b3f348933c3dcc177239787ff47f735713 voted for 97fb37fc855e86a02eb446194cd4b1af6e2eef0c 1

12960:X 05 Jun 2019 17:55:36.536 # 742697f27e4d368be4ac2f204a3d1787cd3a96be voted for 97fb37fc855e86a02eb446194cd4b1af6e2eef0c 1

12960:X 05 Jun 2019 17:55:36.617 # +elected-leader master mymaster 127.0.0.1 6379

这段日志就已经表明了 26380 作为领导者来负责故障转移工作。

12960:X 05 Jun 2019 17:55:36.617 # +failover-state-select-slave master mymaster 127.0.0.1 6379

寻找合适的从节点作为新的主节点。

12960:X 05 Jun 2019 17:55:36.719 # +selected-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379

选择 6381 作为新的主节点。

12960:X 05 Jun 2019 17:55:36.719 * +failover-state-send-slaveof-noone slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379

命令 6381 执行 slaveofnoone 命令,使其变成主节点。

12960:X 05 Jun 2019 17:55:36.773 * +failover-state-wait-promotion slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379

12960:X 05 Jun 2019 17:55:37.637 # +promoted-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379

等待和确认 6381 变成主节点。

12960:X 05 Jun 2019 17:55:37.638 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6379

故障转移进入重新配置从节点阶段。

12960:X 05 Jun 2019 17:55:37.706 * +slave-reconf-sent slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379

命令 6380 节点发送 slaveof 命令,复制新的主节点。

12960:X 05 Jun 2019 17:55:38.686 * +slave-reconf-inprog slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379

12960:X 05 Jun 2019 17:55:38.686 * +slave-reconf-done slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379

6380 节点完成对 6381 节点的复制。

12960:X 05 Jun 2019 17:55:38.762 # +failover-end master mymaster 127.0.0.1 6379

故障转移顺利完成。

12960:X 05 Jun 2019 17:55:38.762 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6381

故障转移完成后,发布主节点的切换消息。

到这里整个故障转移工作已经完成了。

  • (3) 将 6379 启动,执行命令 redis-cli-p6380info replication,如下图:

56f5abc9c33bb8242ce733330166a7f7.png

我们发现,6379 自动变成了 6381 的从节点

  • (4)在故障转移阶段,哨兵和主从节点的配置文件都会被改写

哨兵节点的配置,监控主节点将会变成 6381,从节点有 6379、6381 两个节点,如下图:

3db4fef9003e3ef9e003e14e9d38d0b0.png

至于主从节点,你会发现 6379、6380 的配置文件末尾多了一行 replicaof127.0.0.16381

705419bed1a7e85f618f5b3491d063f5.png

参考资料

  • 《Redis 开发与运维》

往期精彩

【死磕 Redis】----- 开篇

【死磕 Redis】----- Redis 通信协议 RESP

【死磕 Redis】----- Redis 的线程模型

【死磕 Redis】----- 事务

【死磕 Redis】----- 理解 pipeline 管道

【死磕 Redis】----- 布隆过滤器

【死磕 Redis】----- 发布与订阅

【死磕 Redis】-----如何排查 Redis 中的慢查询

【死磕 Redis】-----持久化

【死磕 Redis】----- 主从复制(一):概述

【死磕 Redis】----- 主从复制(二):全量复制和部分复制

【死磕 Redis】----- 主从复制(三):注意的问题

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值