深入理解Redis哨兵搭建及原理

一、什么是Redis Sentinel,为什么我们需要使用Redis Sentinel

谈Redis Sentinel之前,再回顾一下Redis的主从复制。在主从复制模式下我们可以将主节点的改变的数据同步给从节点,这样从节点可以用作主节点数据的一个备份,在主节点故障宕机的情况下,从节点可以当作备用机顶上来。并且在一主多从的拓扑结构中,从节点能拓展主节点的读的能力,读写分离,在并发量很大的时候从节点一定程度上能帮主节点分担一部分压力。主从复制虽然带来了很多好处,但也存在这么一些问题:

  • 倘若主节点出现了故障,我们就得人工将一个从节点晋升为一个主节点,然后修改其他的从节点的主从复制,修改应用的主节点的地址,并且人工控制不能保证即使行
  • 主节点写入与存储的能力受到单个机器的限制

Redis Sentinel主要解决的就是第一点,实现Redis高可用的一个方案。在没有Redis Sentinel之前我们主节点故障通常都是走的以下的流程

  1. 主节点发生了故障,导致客户端连接失败并且从节点复制失败
  2. 若主节点无法正常启动的情况下,就会选择一个从节点进行slave of no one 的操作,让它重新晋升为主节点
  3. 更新软件应用的主节点的信息
  4. 使用slave of {newMaster} ,与新的主节点建立复制关系。
  5. 原来的主节点恢复后与新的主节点建立复制关系,降为从节点

图解如下:

1、主节点发生了故障

2、从节点晋升为主节点

3、更新应用连接新的主节点

4、其他的从节点与新的主节点建立复制关系

5、原来的主节点恢复后与新的主节点建立复制关系,降为从节点

二、Redis一主二从三哨兵搭建实践

首先先开启三个Redis实例,端口分别为6379、59975、59976,主节点端口为6379,从节点端口分别为59975、59976。

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=55975,state=online,offset=312537,lag=0
slave1:ip=127.0.0.1,port=55976,state=online,offset=312537,lag=0
master_repl_offset:312537
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:312536
127.0.0.1:55975> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0
slave_repl_offset:312481
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
127.0.0.1:55976> 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:5951
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

然后开启三个哨兵实例,端口分别为61112、61113、61134。哨兵的配置信息基本如下

bind 127.0.0.1
port 61111
logfile "sentinel1.log"
dir "E:\\redis_sentinel"
sentinel monitor leemaster 127.0.0.1 55975 2
sentinel down-after-milliseconds leemaster 20000
sentinel auth-pass leemaster 123456 #没有密码可注释
sentinel parallel-syncs leemaster 1 #最多同时有几台从节点与主节点全量复制
sentinel failover-timeout leemaster 180000

 三台sentinel的基本信息如下:

127.0.0.1:61111> 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=leemaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3

 

127.0.0.1:61112> 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=leemaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3

 

127.0.0.1:61113> 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=leemaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3

这个时候我手动模拟主redis实例故障,查看哨兵的日志。

[18576] 01 Oct 19:54:52.838 # +sdown master leemaster 127.0.0.1 6379
[18576] 01 Oct 19:54:52.910 # +odown master leemaster 127.0.0.1 6379 #quorum 2/2
[18576] 01 Oct 19:54:52.910 # +new-epoch 1
[18576] 01 Oct 19:54:52.910 # +try-failover master leemaster 127.0.0.1 6379
[18576] 01 Oct 19:54:52.913 # +vote-for-leader 1dc7257f6ea2f383359ef829e14209c008a626ed 1
[18576] 01 Oct 19:54:52.924 # 22bf696c6832a735dddcedfe080955c0961aa7df voted for 1dc7257f6ea2f383359ef829e14209c008a626ed 1
[18576] 01 Oct 19:54:52.925 # c4fb62082472dd171b9f6d27a149a2eeacbbf0bb voted for 1dc7257f6ea2f383359ef829e14209c008a626ed 1
[18576] 01 Oct 19:54:52.990 # +elected-leader master leemaster 127.0.0.1 6379
[18576] 01 Oct 19:54:52.990 # +failover-state-select-slave master leemaster 127.0.0.1 6379
[18576] 01 Oct 19:54:53.059 # +selected-slave slave 127.0.0.1:55975 127.0.0.1 55975 @ leemaster 127.0.0.1 6379
[18576] 01 Oct 19:54:53.059 * +failover-state-send-slaveof-noone slave 127.0.0.1:55975 127.0.0.1 55975 @ leemaster 127.0.0.1 6379
[18576] 01 Oct 19:54:53.160 * +failover-state-wait-promotion slave 127.0.0.1:55975 127.0.0.1 55975 @ leemaster 127.0.0.1 6379
[18576] 01 Oct 19:54:54.019 # +promoted-slave slave 127.0.0.1:55975 127.0.0.1 55975 @ leemaster 127.0.0.1 6379
[18576] 01 Oct 19:54:54.019 # +failover-state-reconf-slaves master leemaster 127.0.0.1 6379
[18576] 01 Oct 19:54:54.076 * +slave-reconf-sent slave 127.0.0.1:55976 127.0.0.1 55976 @ leemaster 127.0.0.1 6379
[18576] 01 Oct 19:54:55.077 * +slave-reconf-inprog slave 127.0.0.1:55976 127.0.0.1 55976 @ leemaster 127.0.0.1 6379
[18576] 01 Oct 19:54:55.127 # -odown master leemaster 127.0.0.1 6379
[18576] 01 Oct 19:57:54.072 # +failover-end-for-timeout master leemaster 127.0.0.1 6379
[18576] 01 Oct 19:57:54.072 # +failover-end master leemaster 127.0.0.1 6379
[18576] 01 Oct 19:57:54.072 * +slave-reconf-sent-be slave 127.0.0.1:55975 127.0.0.1 55975 @ leemaster 127.0.0.1 6379
[18576] 01 Oct 19:57:54.072 * +slave-reconf-sent-be slave 127.0.0.1:55976 127.0.0.1 55976 @ leemaster 127.0.0.1 6379
[18576] 01 Oct 19:57:54.072 # +switch-master leemaster 127.0.0.1 6379 127.0.0.1 55975
[18576] 01 Oct 19:57:54.074 * +slave slave 127.0.0.1:55976 127.0.0.1 55976 @ leemaster 127.0.0.1 55975
[18576] 01 Oct 19:57:54.074 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ leemaster 127.0.0.1 55975

这时分析日志可以发现:

  • 主Redis实例故障后,哨兵主观认为主实例挂了(sdown),其他哨兵也认为主Redis实例挂了,这时就变成了客观下线代表主实例真的挂了(odown)。

  • 这时哨兵们进行投票选出一个leader来进行故障转移工作我们发现都投票给了sentinel1

  • 最后选择了55975作为新的master,然后与老master6379,55976建立起了复制关系

最后我把老的主Redis实例重新启动后,发现老的6379端口Redis主实例也与新的主实例55975建立了主从关系,证明与上述的流程一样

127.0.0.1:55975> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6379,state=online,offset=88301,lag=0
slave1:ip=127.0.0.1,port=55976,state=online,offset=88301,lag=0
master_repl_offset:88301
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:88300

Redis哨兵原理分析

1.哨兵配置文件详解

配置一:sentinel monitor <master-name> <ip> <port> <quorum>

  • 这个配置表达的是 哨兵节点定期监控 名字叫做 <master-name>  并且 IP 为 <ip> 端口号为 <port> 的主节点。<quorum> 表示的是哨兵判断主节点是否发生故障的票数。也就是说如果我们将<quorum>设置为2就代表至少要有两个哨兵认为主节点故障了,才算这个主节点是客观下线的了,一般是设置为sentinel节点数的一半加一。

配置二:sentinel down-after-milliseconds <master-name> <times>

  • 每个哨兵节点会定期发送ping命令来判断Redis节点和其余的哨兵节点是否是可达的,如果超过了配置的<times>时间没有收到pong回复,就主观判断节点是不可达的,<times>的单位为毫秒。

配置三:sentinel parallel-syncs <master-name> <nums>

  • 当哨兵节点都认为主节点故障时,哨兵投票选出的leader会进行故障转移,选出新的主节点,原来的从节点们会向新的主节点发起复制,这个配置就是控制在故障转移之后,每次可以向新的主节点发起复制的节点的个数,最多为<nums>个,因为如果不加控制会对主节点的网络和磁盘IO资源很大的开销。

配置四:sentinel failover-timeout <master-name>  <times>

  • 这个代表哨兵进行故障转移时如果超过了配置的<times>时间就表示故障转移超时失败。

配置五: sentinel auth-pass <master-name> <password>

  • 如果主节点设置了密码,则需要这个配置,否则哨兵无法对主节点进行监控。

2.哨兵实现原理

  • Redis哨兵的三个定时任务,Redis哨兵判定一个Redis节点故障不可达主要就是通过三个定时监控任务来完成的:
  1. 每隔10秒每个哨兵节点会向主节点和从节点发送"info replication" 命令来获取最新的拓扑结构 
  2. 每隔2秒每个哨兵节点会向Redis节点的_sentinel_:hello频道发送自己对主节点是否故障的判断以及自身的节点信息,并且其他的哨兵节点也会订阅这个频道来了解其他哨兵节点的信息以及对主节点的判断
  3. 每隔1秒每个哨兵会向主节点、从节点、其他的哨兵节点发送一个 “ping” 命令来做心跳检测

定时任务1:

定时任务2:

定时任务3:

  • 主观下线与客观下线
  1. 哨兵节点由定时任务3,每隔1秒会向主节点、从节点、其他的哨兵节点发送ping命令做心跳检测,如果这些被监控的节点在配置的down-after-milliseconds时间内没有pong回复,哨兵就会主观的判断这个节点故障不可达了,也就是日志里面记录的sdown。
  2. 当哨兵判断主观下线的节点时主节点的时候,就会通过sentinel is-master-down-by-addr 命令向其他的哨兵节点询问它们对主节点进行的判断,如果其他的哨兵也认为主节点主观线下了,则当认为主观下线的票数超过了<quorum>数时,那么这个主节点确实就可能是故障不可达了,这时就由原来的主观下线sdown变为了客观下线odown。

  •  故障转移哨兵leader选举

如果主节点被判定为客观下线之后,就要选取一个哨兵节点来完成后面的故障转移工作,选举出一个leader的流程如下:

  1. 每一个哨兵节点都可以成为leader完成故障转移工作,这时它会向其他的哨兵发送 sentinel is-master-down-by-addr,请求当leader
  2. 收到请求的哨兵节点如果没有把自己那唯一一张票数投出去,则投给请求者同意请求者当选leader,否则拒绝
  3. 哨兵如果发现自己得到的票数大于等于max(quorums,哨兵数/2 +1 ),则它就成为了leader
  4. 如果这一轮没有选出leader,那么就开始下一轮的选举
  • 故障转移

故障转移也就是在从节点中选出一个节点来当新的主节点,选择的流程如下:

  1. 过滤掉主观下线的节点 
  2. 选择slave-priority最高的节点,如果由则返回没有就继续选择
  3. 选择出复制偏移量最大的系节点,因为复制便宜量越大则数据复制的越完整,如果由就返回了,没有就继续
  4. 选择run_id最小的节点

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值