主从复制架构
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节点也可以执行写操作,但是不建议这么做。
2. 架构图
3. 缺陷
主从复制架构无法解决故障自动转移的问题。
4. 搭建
使用原生搭建和Docker搭建都可以,具体搭建方式自行百度。
哨兵机制架构
1. 说明
Sentinel(哨兵)是Redis的高可用性解决方案。
由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主从架构,包括多个Master节点以及这些Master节点属下的所有Slave节点。并可以在被监视的Master节点进入下线状态时,自动将下线的Master节点属下的某个Slave节点升级为新的Master节点。
在哨兵机制架构中,同样也只有Master节点对外提供服务,从属的Slave节点只负责同步Master节点的数据。
简单的说,哨兵机制就是带有自动故障转移功能的主从复制架构。
2. 架构图
哨兵集群会不断地检测每一个节点的心跳。
所谓心跳,就是哨兵集群定时向每一个节点发一个数据包,节点收到数据包后在规定时间内返回给哨兵集群一个数据包,如果哨兵集群在规定时间内接收到数据包,则判定该节点是健康的。
如果某一个时间,哨兵集群发现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中做开启远程连接的相应配置。