【Redis】5. Redis主从复制和哨兵机制

886 阅读5分钟

主从复制架构

1. 说明

Redis主从复制架构仅仅用来解决数据的冗余备份问题,并不能保证系统的高可用。

在主从复制架构中,主节点Matser对外提供服务,从节点Slave不对外提供服务。从节点仅仅用来同步Master节点的数据,只要Master节点数据发生变化,Slave节点就会立刻同步数据。

主从复制架构并不常用,因为主从复制架构不具备故障的自动转移机制,如果Master节点故障,Slave节点不能代替Master节点成为新的Master节点。

为什么要同步Master节点的数据呢?

因为Master节点上存储的数据非常重要,如果在某一时刻Master节点出现不可抗的因素(自然灾害,断电,硬件老化等),都会导致Master节点中的数据丢失。为了不让缓存中的数据丢失,Redis也提供了数据持久化方案,但是该持久化方案只会将数据存储在本地,如果节点故障,数据照样会丢失。因此Redis提供了一套主从复制的架构,让Slave节点来同步Master节点的数据。

从节点就一定不能对外提供服务嘛?

我们说从节点不对外提供服务的实际情况是,从Redis 2.6 以来,Slave节点默认就是只读模式(read-only),只能读,不能写。但是可以在Slave节点的 redis.conf 中修改Slave节点的模式,从而让Slave节点也可以执行写操作,但是不建议这么做。

20210922153009.png

2. 架构图

20210922200913.png

3. 缺陷

主从复制架构无法解决故障自动转移的问题。

4. 搭建

使用原生搭建和Docker搭建都可以,具体搭建方式自行百度。

哨兵机制架构

1. 说明

Sentinel(哨兵)是Redis的高可用性解决方案。

由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主从架构,包括多个Master节点以及这些Master节点属下的所有Slave节点。并可以在被监视的Master节点进入下线状态时,自动将下线的Master节点属下的某个Slave节点升级为新的Master节点。

在哨兵机制架构中,同样也只有Master节点对外提供服务,从属的Slave节点只负责同步Master节点的数据。

简单的说,哨兵机制就是带有自动故障转移功能的主从复制架构

2. 架构图

20210922195423.png

哨兵集群会不断地检测每一个节点的心跳。

所谓心跳,就是哨兵集群定时向每一个节点发一个数据包,节点收到数据包后在规定时间内返回给哨兵集群一个数据包,如果哨兵集群在规定时间内接收到数据包,则判定该节点是健康的。

如果某一个时间,哨兵集群发现Master节点不健康,那么哨兵就会判断Master节点可能宕机了。此时,Slave1和Slave2全部终止同步数据,哨兵集群通过选举机制会在多个Slave节点中选出一个作为新的Master节点,其他的Slave节点开始同步新Master节点的数据。如果某一时刻,原Master节点恢复了正常,那么哨兵集群会将原Master节点作为新Master节点的一个Slave节点。通过这种机制,不断循环,从而保证系统的高可用

3. 缺陷

哨兵机制架构虽然解决了故障转移的问题,但是无法解决单节点压力问题单节点物理上限问题

Redis所有数据都在内存中,所有客户端都去访问对外提供服务的Master节点,因此对Master节点的要求非常高。当同一时刻,大量请求到达Master节点,Master应对大规模并发时,会出现单节点压力问题。因为Redis会开启持久化,如果是AOF持久化,AOF文件会随着时间越来越大,会出现单节点物理上限问题。

要解决单节点压力和物理上限问题,只有Redis集群

4. 搭建

在搭建哨兵时,建议不要就搭建一个哨兵,至少搭建两个或三个组建一个集群。因为如果只有一个哨兵,可能会因为网络延迟中断,误判断Master节点宕机,然会选出一个新的Master节点顶替原Master节点,但是原Master节点此时可能并没有故障还在继续工作,那么集群就可能出现 "脑裂" (两个首领)的问题。

搭建哨兵需要基于主从复制架构来搭建,具体配置方法自行百度。

Spring Boot整合哨兵机制

之前Spring Boot整合Redis的方案是Redis单节点连接,如果要搭建主从复制架构也可以使用前文的整合方案。因为在单节点连接和主从复制架构中,Master节点是不会变化的。

在哨兵机制中,Master是会不断变化的。因此在配置中,无需指定某一个特定的节点,因为在Master节点变化之后,我们也不清楚谁是Master节点,谁是Slave节点。我们不知道,但是哨兵知道,所以我们只需对哨兵进行配置即可,Spring Data Redis中整合的API是不变的。

application.yml 中配置如下:

Spring:
  redis:
    sentinel:
      # 哨兵集群监听的主从架构的名字,在sentinel.conf中配置
      master: postilhub
      # 所有哨兵,多个哨兵之间逗号隔开
      nodes: 192.168.202.206:26379,192.168.202.207:26379

由于这里的哨兵是Redis提供的一个机制,所以哨兵节点默认是不开启远程访问的,我们如果想访问哨兵,则需要在 sentinel.conf 中做开启远程连接的相应配置。