一、前言

说到Redis的部署模式,很多同学第一时间想到的就是Redis Cluster集群模式,因为它可能是现在的主流模式。但其实这几种模式各有优劣,实际环境中我们应该选择合适的部署模式,否则适得其反,接下来简单介绍一下这几种部署模式

二、部署模式

2.1 单机模式

单机模式就是只有单个redis提供服务,如下图
image.png

  • 优点:

    1. 架构简单,易于维护
  • 缺点:

    1. 单台服务器内存空间有限,无法存放太多的数据量
    2. 存在单点故障
    3. 读写压力较大

单机模式适用于内部测试、项目规模小的场景

2.2 主从模式

由于单个redis节点的读写压力较大,所以引出了主从复制方式,可实现读写分离,读操作可以由slave节点来支持,降低master节点的压力。如下图
image.png

主从复制是redis实现高可用的基石,后续的两种高可用方案 哨兵模式 或者 cluster集群模式 都需要有主从复制的支撑。
  • 优点:

    1. 读写分离。通过读写分离来降低master节点的压力
    2. 拥有多个数据副本
  • 缺点:

    1. 单个master内存空间有限,无法存放太多的数据量
    2. 依然只有master节点可以处理写请求,存在瓶颈
    3. 当master节点发生故障下线时,需要人工地将某个slave节点切换为新的master节点,并且客户端需要切换到连接新的master节点

主从模式适用于内部性能测试、项目规模小的场景

2.3 哨兵模式

哨兵模式是在主从复制的基础上,添加哨兵(实际上就是个redis的应用进程)来监控master节点和slave节点,当master节点发生故障下线时,哨兵自动地将某个slave节点切换为master节点,且客户端不需要去切换连接新的master节点。(一般需要部署哨兵集群,防止哨兵的单点故障)
image.png

  • 优点:

    1. 读写分离。通过读写分离来降低master节点的压力
    2. 拥有多个数据副本
    3. 自动故障转移。当master节点发生故障下线时,哨兵自动地将某个slave节点切换为新的master节点,并且客户端不需要切换连接新的master节点(由于客户端连接哨兵集群,而不直接连接master节点)
  • 缺点:

    1. 单个master内存空间有限,无法存放太多的数据量
    2. 依然只有master节点可以处理写请求,存在瓶颈

哨兵模式适用于生产环境、项目规模中等的场景

2.3.1 故障转移 failover

当master节点下线之后,哨兵自动将slave节点切换为新的master节点,这一过程称为故障转移(failover)。故障转移的大致步骤如下:

  1. 检测master是否主观下线
    sentinel每隔1秒钟,向所有的master、slave、sentinel发送ping命令,通过其他服务器的回复来判断是否在线(当ping的实例在连续down-after-milliseconds配置的时间内返回无效命令或无响应,则当前sentinel认为其主观下线,对所有master、slave、sentinel都适用)
  2. 检测master是否客观下线
    当前sentinel要想判断master是否客观下线,需要询问其他sentinel,并且认为master主观下线的总数需要达到quorum配置的值,则当前sentinel将该master标记为客观下线
  3. 选举哨兵leader
    当前sentinel将该master标记为客观下线后,会给其他sentinel再发送命令,其他sentinel收到请求后将其设置为leader(这个设置是先到先得的,sentinel先收到谁的设置请求,就将谁设置为leader)。发送命令的sentinel会根据其他sentinel回复的结果来判断自己是否被该sentinel设置为leader,如果当前sentinel被其他sentinel设置为leader的数量超过半数sentinel,那么当前sentinel会认为自己已经成为leader,并开始后续故障转移工作。如果没有任何一个sentinel达到成为leader的要求,将会重新选举直到产生leader为止
  4. 故障转移由哨兵leader全权负责
    从slave列表中选择最佳的slave作为新的master。让其他slave复制新的master,并且继续监听旧master,如果其上线,将其设置为新的master的slave

2.4 集群模式

既然哨兵模式已经具备了高可用性,为什么还需要cluster模式?因为哨兵模式还是没有解决只有master节点可以处理写的问题,依然存在写瓶颈。而cluster集群模式使用"分片"(每个master处理一部分slot)的形式来处理所有key,可以有多个master来处理写操作,从而来解决写瓶颈问题。如下图
image.png

  • 优点:

    1. 自动故障转移。当某个master节点发生故障下线时,集群自动地将其对应的某个slave节点替代它
    2. 当现有redis集群不足以支撑整个系统的压力时,可以横向拓展集群
  • 缺点:

    1. 无法执行批量操作,如mget
    2. 当redis节点很多的时候,由于每个节点都需要跟其他节点通信,整个集群的性能会降低
    3. 维护成本较高

redis cluster模式适用于生产环境、项目规模大型的场景

2.4.1 故障转移 failover

与哨兵模式一样,从节点的故障并不会影响集群工作,对应的主节点只会记住自己的哪个从节点下线了,当从节点重连后,会继续复制主节点的数据。

只有主节点故障才需要故障转移。cluster集群模式不需要哨兵,自身已具备了故障转移功能。由于集群内的每个节点都会互相进行通信,节点之间通过gossip协议进行通信,通过这种机制来发现故障并进行故障转移。但是要达到故障转移,需要解决几个问题?

  • 故障发现:如何判断某个master节点故障了?redis采用多数投票的方案
  • 选取slave节点:master有多个slave节点的时候,应该选择哪个slave节点成为新的master

故障发现
和哨兵模式类似,故障发现也经历两个阶段:PFAIL(主观下线)和FAIL(客观下线)
假设现在有3个master节点,分别为节点1,节点2,节点3。比如节点1判断节点3下线,那么它会标记节点3的状态为PFAIL,节点1会通过gossip协议把这个信息发送给其他节点,接收到信息的节点会进行对节点3客观下线的状态判定。当集群中有超过半数的节点认为节点3处于PFAIL,那么节点1就判定节点3为FAIL,并立即向集群所有节点(包括节点3的子节点)广播这个信息。

故障转移
当节点3的slave发现自己的master变为fail状态时,便尝试进行故障转移failover,以成为新的master。由于一个master可能有多个slave,所以这些slave需要竞争成为master节点,过程如下:

  1. slave1、slave2都发现自己的master状态变为fail
  2. 它们将自己记录的集群currentEpoch(选举周期)加1,并使用gossip协议广播failover_auth_request信息
  3. 其他master节点收到slave1和slave2的消息,会给slave1或slave2发送failover_auth_ack,在一个选举周期中,一个master只会响应第一个给它发消息的slave
  4. slave们收集返回的failover_auth_ack,当收到超过半数的master的ack消息后变成新的master
  5. 最后向整个集群广播现在自己是master,同时负责旧master所有slots的信息
  6. 其他节点接收到信息后,更新自己的维护状态

三、总结

redis的部署模式介绍到这里,总体看下来redis cluster集群模式的利大于弊,所以在较大规模的项目中一般使用该模式,但在中小规模的项目中,选择主从模式 或 哨兵模式亦可。


kamier
1.5k 声望493 粉丝