在Redis中提供的集群方案总共有三种

  • 主从复制
  • 哨兵模式
  • 分片集群

一、主从复制 

Redis的主从同步: 

单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。一般都是一主多从,主节点负责写数据,从节点负责读数据。

Redis中针对集群的所_redis

主从数据同步原理

主从同步数据的流程: 

主从全量同步

  1. 从节点请求主节点同步数据(replication id、offset)
  2. 主节点判断是否是第一次请求,是第一次请求就与从节点同步版本信息(replication id、offset)
  3. 主节点执行bgsave,生成rdb文件后,发送给从节点去执行
  4. 在rdb生成执行期间,主节点会以命令的方式记录到缓冲区(一个日志文件)
  5. 把生成之后的命令日志文件发送给从节点进行同步

Redis中针对集群的所_java_02

需要知道的 两个概念

Replication Id:简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid。

offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave的数据落后于master,需要更新。

 

Redis中针对集群的所_java_03

增量同步(slave重启或后期数据变化)

  1. 从节点请求主节点同步数据,主节点判断是否第一次请求,不是第一次就获取从节点的offset值
  2. 主节点从命令日志中获取offset值之后的数据,发送给从节点进行数据同步

第一次同步: 

Redis中针对集群的所_Redis_04

 第二次同步:

Redis中针对集群的所_Redis中针对集群的所_05

二、哨兵模式

 哨兵的作用 

Redis提供了哨兵(Sentinel)机制来实现主从集群的自动故障恢复。哨兵的结构和作用如下: 

  • 监控: 哨兵(Sentinel)会不断检查您的master和slave是否按预期工作 
  • 自动故障恢复:如果master故障,哨兵(Sentinel)会将一个slave提升为master当故障实例恢复后也以新的master为主
  • 通知:哨兵(Sentinel)充当Redis客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给Redis的客户端

Redis中针对集群的所_Redis_06

 怎么保证redis的高并发高可用

哨兵模式:实现主从集群的自动故障恢复(监控、自动故障恢复、通知)

使用redis的单点还是集群

主从(1主1从)+哨兵就可以了。单节点不超过10G内存,如果Redis内存不足则可以给不同服务分配独立的Redis主从节点 

解决redis集群脑裂

集群脑裂是由于主节点和从节点和哨兵(Sentinel)处于不同的网络分区,使得哨兵(Sentinel)没有能够心跳感知到主节点,所以通过选举的方式提升了一个从节点为主,这样就存在了两个master,就像大脑分裂了一样,这样会导致客户端还在老的主节点那里写入数据,新节点无法同步数据,当网络恢复后,哨兵(Sentinel)会将老的主节点降为从节点,这时再从新的master同步数据,就会导致数据丢失

解决:我们可以修改redis的两个配置,可以设置最少的从节点数量以及锁定主从数据同步的延迟时间,达不到要求就拒绝客户端的请求,就可以避免大量的数据丢失

Redis中针对集群的所_redis_07

 三、分片集群

分片集群结构

主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决:

  • 海量数据存储问题
  • 高并发写的问题

使用分片集群可以解决上述问题,分片集群特征:

  • 集群中有多个master,每个master保存不同数据 
  • 每个master都可以有多个slave节点
  • master之间通过ping监测彼此健康状态
  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点

Redis中针对集群的所_缓存_08

分片集群结构---数据读写

Redis分片集群引入了哈希槽的概念,Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。

 

Redis中针对集群的所_Redis中针对集群的所_09


我们可以设置key的有效部分,就是可以按照一定的规则来选择存储到哪个节点中,如果设置了{}大括号,那大括号就是有效部分,如果没有设置大括号,key本身就是有效部分

Redis中针对集群的所_缓存_10

 分配集群结构---总结:

分片集群中数据是怎么存储和读取的?

  • Redis分片集群引入了哈希槽的概念,Redis集群有16384个哈希槽
  • 将16384个插槽分配到不同的实例
  • 读写数据:根据key的有效部分计算哈希值,对16384取余(有效部分:如果key前面有大括号,大括号的内容就是有效部分,如果没有,则以key本身做为有效部分)余数做为插槽,寻找插槽所在的实例