在Redis中提供的集群方案总共有三种
- 主从复制
- 哨兵模式
- 分片集群
一、主从复制
Redis的主从同步:
单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。一般都是一主多从,主节点负责写数据,从节点负责读数据。
主从数据同步原理
主从同步数据的流程:
主从全量同步
- 从节点请求主节点同步数据(replication id、offset)
- 主节点判断是否是第一次请求,是第一次请求就与从节点同步版本信息(replication id、offset)
- 主节点执行bgsave,生成rdb文件后,发送给从节点去执行
- 在rdb生成执行期间,主节点会以命令的方式记录到缓冲区(一个日志文件)
- 把生成之后的命令日志文件发送给从节点进行同步
需要知道的 两个概念:
Replication Id:简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid。
offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave的数据落后于master,需要更新。
增量同步(slave重启或后期数据变化)
- 从节点请求主节点同步数据,主节点判断是否第一次请求,不是第一次就获取从节点的offset值
- 主节点从命令日志中获取offset值之后的数据,发送给从节点进行数据同步
第一次同步:
第二次同步:
二、哨兵模式
哨兵的作用
Redis提供了哨兵(Sentinel)机制来实现主从集群的自动故障恢复。哨兵的结构和作用如下:
- 监控: 哨兵(Sentinel)会不断检查您的master和slave是否按预期工作
- 自动故障恢复:如果master故障,哨兵(Sentinel)会将一个slave提升为master当故障实例恢复后也以新的master为主
- 通知:哨兵(Sentinel)充当Redis客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给Redis的客户端
怎么保证redis的高并发高可用
哨兵模式:实现主从集群的自动故障恢复(监控、自动故障恢复、通知)
使用redis的单点还是集群
主从(1主1从)+哨兵就可以了。单节点不超过10G内存,如果Redis内存不足则可以给不同服务分配独立的Redis主从节点
解决redis集群脑裂
集群脑裂是由于主节点和从节点和哨兵(Sentinel)处于不同的网络分区,使得哨兵(Sentinel)没有能够心跳感知到主节点,所以通过选举的方式提升了一个从节点为主,这样就存在了两个master,就像大脑分裂了一样,这样会导致客户端还在老的主节点那里写入数据,新节点无法同步数据,当网络恢复后,哨兵(Sentinel)会将老的主节点降为从节点,这时再从新的master同步数据,就会导致数据丢失
解决:我们可以修改redis的两个配置,可以设置最少的从节点数量以及锁定主从数据同步的延迟时间,达不到要求就拒绝客户端的请求,就可以避免大量的数据丢失
三、分片集群
分片集群结构
主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决:
- 海量数据存储问题
- 高并发写的问题
使用分片集群可以解决上述问题,分片集群特征:
- 集群中有多个master,每个master保存不同数据
- 每个master都可以有多个slave节点
- master之间通过ping监测彼此健康状态
- 客户端请求可以访问集群任意节点,最终都会被转发到正确节点
分片集群结构---数据读写
Redis分片集群引入了哈希槽的概念,Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。
我们可以设置key的有效部分,就是可以按照一定的规则来选择存储到哪个节点中,如果设置了{}大括号,那大括号就是有效部分,如果没有设置大括号,key本身就是有效部分
分配集群结构---总结:
分片集群中数据是怎么存储和读取的?
- Redis分片集群引入了哈希槽的概念,Redis集群有16384个哈希槽
- 将16384个插槽分配到不同的实例
- 读写数据:根据key的有效部分计算哈希值,对16384取余(有效部分:如果key前面有大括号,大括号的内容就是有效部分,如果没有,则以key本身做为有效部分)余数做为插槽,寻找插槽所在的实例