1.描述
哨兵(sentinel)是redis主从结构中的一个重要组件,其也是一个redis服务,不过是一个特殊的redis服务,只用来监听redis示例,不负责数据的读写。
2.作用
- 监控:会不断监控主节点和从节点是否正常运行
- 自动故障转移:当主节点挂掉后,会进行自动转移,将其中一个从节点变为主节点,主节点变为该节点的从节点。
- 配置提供者:客户端再初始化时通过哨兵来获取当前Redis的主节点地址
- 通知:将故障转移的结果通知给客户端
其中最核心的功能是监控和自动故障转移主节点。
3.搭建
本次搭建一个简单的哨兵系统,包括一主两从和三个哨兵节点。本次所有的节点都部署再本地电脑上127.0.0.1
1.搭建主从节点
搭建一主二从节点,和前面的搭建主从复制一样,不过是多了一个从节点而已。主节点的端口设置为6379,两个从节点端口为6380和6381。具体的配置如下:
#6379端口的配置
port 6379
logfile "6379.log"
#6380端口的配置
port 6380
logfile "6380.log"
slaveof 127.0.0.1 6379
#6381端口的配置
port 6381
logfile "6381.log"
slaveof 127.0.0.1 6379
配置好之后分别启动上面的三个服务。启动好之后,连接主节点,查看主从状态信息:
可以看到6379是主节点,其从节点有两个,分别是6380和6381
2.搭建哨兵节点
哨兵节点也是三个(哨兵节点的数量最少为3个,是为了防止哨兵节点故障从而导致选领导者失败无法进行故障转移,如果允许故障的哨兵节点数量较多则可以增加哨兵节点的数量),三个哨兵节点监听主节点情况,具体的配置如下:
#26379端口的配置
port 26379
logfile "26379.log"
sentinel monitor mymaster 127.0.0.1 6379 2
#26380端口的配置
prot 26380
logfile "26380.log"
sentinel monitor mymaster 127.0.0.1 6379 2
#26381端口的配置
port 26381
logfile "26381.log"
sentinel monitor mymaster 127.0.0.1 6379 2
其中sentinel monitor mymaster 127.0.0.1 6379 2
配置的意思是,该从节点监控127.0.0.1 6379
这个主节点,主节点的名字为mymaster,最后的2表示当有两个或两个以上的哨兵判断该主节点故障,则认为主节点故障,进行故障转移,将主节点标记为客观下线(下线分为客观下线和主管下线,客观下线是大于等于配置的redis哨兵节点认为该主节点下线。主观下线就是当前哨兵节点认为该主节点下线。即客观下线是对所有哨兵都下线,主观下线只是对认为主节点下线的哨兵下线。)。
配置好之后,分别启动哨兵节点。如下:
redis-server redis.windows.26379.conf --sentinel
redis-server redis.windows.26380.conf --sentinel
redis-server redis.windows.26381.conf --sentinel
当所有的哨兵节点启动之后可以看到打印的日志为:
可以看到有三个哨兵节点都监听了主节点127.0.0.1 6379
可以看到此时的26379哨兵节点的配置文件后面多了:
# Generated by CONFIG REWRITE
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
sentinel known-slave mymaster 127.0.0.1 6380
sentinel known-slave mymaster 127.0.0.1 6381
sentinel known-sentinel mymaster 127.0.0.1 26381 c5075d74900b0ef6b5d12e74fa23b15769b1e8c3
sentinel known-sentinel mymaster 127.0.0.1 26380 1a71669cf3889cda3b84217996600c70e84e5f23
sentinel current-epoch 0
从上面多出的配置信息可以看出,该哨兵节点发现了主节点的两个从节点6380和6381,同时还发现了另外两个哨兵节点26380和26381。而最后的current-epoch 0 则表示当前纪元为0(纪元是表示主节点选举的次数,主节点选举一次则纪元加一)。
3.主节点停机
此时停掉主节点,然后过一段时间在启动(防止哨兵节点没有发现主节点停机,而没有进行故障转移)。此时再26379哨兵节点看到信息如下:
可以看到此时主节点已经变成了6380。
随后在6380主节点看到从节点的信息为:
可以看到6379端口的节点已经变成了从节点。
同时可以发现哨兵节点26379的最后几行的配置文件也已经变更:
# Generated by CONFIG REWRITE
sentinel config-epoch mymaster 1
sentinel leader-epoch mymaster 1
sentinel known-slave mymaster 127.0.0.1 6381
sentinel known-slave mymaster 127.0.0.1 6379
sentinel known-sentinel mymaster 127.0.0.1 26381 c5075d74900b0ef6b5d12e74fa23b15769b1e8c3
sentinel known-sentinel mymaster 127.0.0.1 26380 1a71669cf3889cda3b84217996600c70e84e5f23
sentinel current-epoch 1
可以看到从节点已经变成了6379和6381,然后纪元变为了1。
4.工作流程
哨兵节点的工作流程大致可以分为四个部分,分别是监控、选主、转移、通知。
监控
监控是指哨兵节点会每隔1秒给所有的主从节点发送ping命令,如果在规定的时间之内,主节点或从节点没有回应哨兵节点,那么该哨兵会认为该节点主观下线。规定的时间是由down-after-milliseconds
参数控制的,单位是毫秒。
对于主节点来说,如果被一个哨兵主观下线之后,那么该哨兵就会向其他哨兵进行通知,让其它哨兵开始校验主节点是否下线,如果认为该主节点下线的哨兵数量达到配置文件中sentinel monitor mymaster 127.0.0.1 6379 2
配置的数量2,那么就会将主节点变为客观下线。
选主
当主节点被判断为客观下线后,哨兵节点首先会选取出一个领导者,选取方式为哨兵节点再确认主节点主观下线后,会像其他的哨兵节点申请成为领导者,其他哨兵节点给予回复,同意则票数加1,最后又哪个哨兵节点得到的票数是哨兵节点数量的一半加1,则该哨兵节点成为领导者。
当哨兵节点的领导者选举出来之后,其会从redis节点中选择一个新的节点作为主节点。而选取主节点的流程为:
- 先过滤掉故障的节点
- 选取剩余节点中优先级
slave-priority
最大的从节点,如果相同则进行下一步判断 - 选择从之前的主节点同步过来数据最多(也就是偏移量最大)的节点,如果相同则进行下一步
- 选择runid最小的节点
转移
当前面的主节点选举出来之后,哨兵的领导者会向被选中的节点发送slaveof no one
命令,让当前节点从从节点变为主节点,同时会每秒一次发送info
命令(没进行故障转移之前,info
命令是每十秒一次)检查该节点是否升级为了主节点。当上面的节点升级为主节点之后,哨兵领导者会向其它节点发送slaveof
命令将其它从节点成为新的主节点的从节点。
通知
转移完成之后,哨兵通过发布者/订阅者机制来通知客户端主节点变更。哨兵会通过+switch-master
频道发布新的主节点的ip和端口信息,然后客户端此时就可以受到新的主节点的ip和端口信息,下次请求就可以使用新的主节点进行通信。
随后会将旧的主节点变更为新的主节点的从节点。
5.总结
哨兵机制主要是使主从复制能够自动进行故障转移,其能够监听主节点的存活状态,如果主节点故障,会自动升级新的主节点。
哨兵节点的数量最少有三个,是为了防止选取哨兵领导者失败,从而不能进行自动故障转移。