Redis集群之哨兵模式

本文来说下Redis集群之哨兵模式


概述

我们知道「主从复制是高可用的基石」,从库宕机依然可以将请求发送给主库或者其他从库,但是 Master 宕机,只能响应读操作,写请求无法再执行。

所以主从复制架构面临一个严峻问题,主库挂了,无法执行「写操作」,无法自动选择一个 Slave 切换为 Master,也就是无法故障自动切换。

在这里插入图片描述

从Redis2.8版本起,提供了一个稳定版本的Sentinel哨兵来解决高可用的问题,它的思路是启动奇数个Sentinel的服务来监控Redis服务器来保证服务的可用性。

启动Sentinel可用用脚本启动,它本质上只是一个运行在特殊模式之下的Redis。Sentinel通过info命令得到被监听Redis机器的master,slave等信息。

./redis-sentinel ../sentinel.conf
# 或者
./redis-server ../sentinel.conf --sentinel

为了保证监控服务器的可用性,我们会对Sentinel做集群部署,Sentinel既监控所有的Redis服务,Sentinel之间也相互监控。 Sentinel本身没有主从之分,地位是平等的,只有Redis服务节点有主从之分。

Sentinel通过Raft共识算法,实现Sentinel选举,选举出一个leader来,由leader完成故障转移。Raft算法的应用很广泛,比如加密货币BTB,Spring Cloud注册中心Consul也用到了Raft算法。Raft算法的核心思想是:先到先得,少数服从多数。Sentinel的Raft实现跟原生的算法是有所区别的,但是大体思想一致

无论Jedis还是Spring Boot(2.x版本默认是Lettuce),都只需要配置全部的哨兵地址,由哨兵返回当前的master节点地址。

哨兵的不足:主从切换的过程中会丢失数据,因为只有一个master;只能单点写,没有解决水平扩容的问题。


哨兵模式

上文咱们说主从复制,在这种一主多从的结构中,我们让主从数据库做到了读写分离,也让从数据库能够完成数据备份的功能,可是也留下了一个比较严重的问题,当master挂了之后,只能由运维人员重新选择一个slave升级成master,然后继续提供服务。这并不符合我们对 Redis 高可用集群的期望。

那么,是不是有一种方法,可以做到不仅仅读高可用,写一样要高可用,当然有,这就是我们今天要介绍的哨兵模式

哨兵模式可以理解成主从模式的一个升级版,主从模式 master 节点和 slave 节点是一开始就定好的,而在哨兵模式中, master 节点是可以转移,一旦发现当前的 master 节点挂掉,通过选举可以指定一个 slave 节点晋升成为 master ,保证在任何情况下,都有 master 节点可以支持写入操作,也间接实现了写高可用。

在这里插入图片描述


什么是哨兵

顾名思义,哨兵其实就是放哨的,它主要会有完成两个功能。

  • 监控整个主数据库和从数据库,观察它们是否正常运行
  • 当主数据库发生异常时,自动的将从数据库升级为主数据库,继续保证整个服务的稳定

哨兵其实是一个独立的进程,如下图

在这里插入图片描述
当然,上图只是一个哨兵存在时的情况,但在现实中还会有两个,甚至更多哨兵存在的情况

在这里插入图片描述


实现原理

当一个哨兵进程启动时,它会先通过配置文件,找我们的主数据库,当然,我们这里也只需要配置其监控的主数据库就好,之后哨兵会自动发现所有复制该主数据库的从数据库,当然一个哨兵是可以监控多个redis系统的,同时,多个哨兵也可以同时监控一个redis系统的,这里moon先给大家灌输下这个概念,大家理解下,详细的我会在后文提到。

哨兵进程启动后后会和master建立两条链接

  • 用来获取其他同样在监控着此redis系统的哨兵信息
  • 发送一个info命令来获取此redis系统master本身的信息

当和master完成链接建立后,该哨兵就会定时的做以下三件事情

  • 每10秒会向master和slave发送info命令
  • 每2秒会向master和slave发送自己的信息
  • 每1秒会向master,slave以及其他同样在监控着此redis系统的哨兵发送ping命令

以上三个操作可是说是哨兵的核心了,下面就着重介绍一下这三个命令

首先,info命令可以让哨兵获取到当前数据库的信息,比如运行id,复制信息等等,从而实现新节点的自动发现,从数据库的信息正是从info命令中获取的,获取从数据库信息后,就会和从数据库建立两条链接,和主数据库建立的链接是完全一样的,之后就会每10s向主从数据库发送info命令,当有新的从数据库加入时,就会从info命令中发现了,从而将这个新的slave加入自己的监控列表中。

当然如果有新的哨兵加入到了监控中,其他哨兵也是从这个info命令中获取的。

于此,就完成了对数据库以及其他哨兵的自动发现和监控,是不是很easy呢??

以上讲了自动发现数据库和其他的哨兵节点,之后哨兵就开始了它的工作,就是去监控这些数据库和节点有没有停止,哨兵就会每隔一段时间向这些节点发送PING命令,如果一段时间没有收到回复后,那么这个哨兵就会认为该节点已经挂了,我们将其称为主观下线

如果该节点是master,哨兵就会向其他节点询问,看其他节点时候也认为该master挂了,我们可以认为他们在投票,当票数达到了一定的次数,那么哨兵就认为该节点真的挂了,我们成为客观下线,然后哨兵之间就会选举,选出一个领头的哨兵对主从数据库发起故障的修复。


哨兵选举过程

哨兵选举过程

  1. 第一个发现该master挂了的哨兵,向每个哨兵发送命令,让对方选举自己成为领头哨兵
  2. 其他哨兵如果没有选举过他人,就会将这一票投给第一个发现该master挂了的哨兵
  3. 第一个发现该master挂了的哨兵如果发现由超过一半哨兵投给自己,并且其数量也超过了设定的quoram参数,那么该哨兵就成了领头哨兵
  4. 如果多个哨兵同时参与这个选举,那么就会重复该过程,知道选出一个领头哨兵

选出领头哨兵后,就开始了故障修复,会从选出一个从数据库作为新的master


master选举过程

master选举过程

  • 从所有在线的从数据库中,选择优先级最高的从数据库
  • 如果有多个优先级高的从数据库,那么就会判断其偏移量,选择偏移量最小的从数据库,这里的偏移量就是增量复制的
  • 如果还是有相同条件的从数据库,就会选择运行id较小的从数据库升级为master

cluster集群模式

在redis3.0版本中支持了cluster集群部署的方式,这种集群部署的方式能自动将数据进行分片,每个master上放一部分数据,提供了内置的高可用服务,即使某个master挂了,服务还可以正常地提供,我们先来看张图:

在这里插入图片描述
使用cluster集群模式,只需要将每个数据库节点的cluster-enabled配置选项打开即可,但是每个cluster集群至少要保证有3个主数据库才能正常运行


cluster集群模式是怎么存放数据的

一个cluster集群中总共有16384个节点,集群会将这16384个节点平均分配给每个节点,当然,我这里的节点指的是每个主节点,就如同下图:

在这里插入图片描述


键是如何和16384个插槽做关联的

redis将每个redis的键的键名有效部分使用CRC16算法计算出散列值,然后与16384取余数,这样的就可以使每个键能够尽量的均匀分布在16384个插槽中。


插槽是如何和节点做关联的

插槽是如何和节点做关联的

  • 插槽之前没有被分配过,现在想分配给指定节点
  • 插槽之前被分配过,现在想移动指定节点

第一种情况可以通过cluster add slot s 命令来实现。第二种情况的原理相对麻烦一点,但是redis也提供的便捷的方式去操作,我们可以使用redis-trib.rb去实现。


如何获取与插槽对应的节点

当客户端向redis集群中的任意一个节点发送命令后,该节点都会判断当前键的信息是否存在于当前节点:

  • 如果存在,那么就会像单机的reids一样执行命令。
  • 如果不存在,就会返回一个move重定向请求,告诉客户端负责该数据的节点是哪一个,然后客户端会向该节点发送命令再次请求获取数据。

新节点的加入

需要通过cluster meet命令来实现:

cluster meet ip port

ip port 是我们已运行的redis集群中任意一个节点的地址和端口号,新节点在客户端输入命令后,会与命令中的节点进行握手,握手后,命令中的集群节点会将这个新节点的信息分享给集群中的每一个节点。


故障恢复

判断故障的逻辑其实与哨兵模式有点类似,在集群中,每个节点都会定期的向其他节点发送ping命令,通过有没有收到回复来判断其他节点是否已经下线。

如果长时间没有回复,那么发起ping命令的节点就会认为目标节点疑似下线,也可以和哨兵一样称作主观下线,当然也需要集群中一定数量的节点都认为该节点下线才可以,我们来说说具体过程:

  • 当A节点发现目标节点疑似下线,就会向集群中的其他节点散播消息,其他节点就会向目标节点发送命令,判断目标节点是否下线
  • 如果集群中半数以上的节点都认为目标节点下线,就会对目标节点标记为下线,从而告诉其他节点,让目标节点在整个集群中都下线

如何提高redis的读写能力

这个问题也是我们之前抛出来的问题,我们放一张图大家就会很容易明白了:

在这里插入图片描述

提高写能力只需要横向扩容master,提高读能力只需要横向扩容slave


本文小结

关于这集群部署的方式,基本上在我知道的公司都毫无疑问直接选择cluster模式,当然具体的选择还是要看公司的规模了,毕竟技术服务于业务,选择合适于当前业务的,就是最好的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值