主从模式、哨兵模式、集群模式
主从集群
提高Redis的可用性和扩展性,读写分离,提高读并发量
主从数据同步
主从数据同步时,首先从节点会发送自己的replid(之前是runid)给master节点,如果不同,说明是全新的集群,对其进行全量同步,如果相同,则进行增量同步,根据offset记录slave目前的数据版本,给slave发送offset之后的数据。如果offset不在复制积压缓存区中,则需全量同步
从节点过期数据
从节点会判断数据是否过期,如果过期,会删除对应数据并返回空值。不要使用ttl作为过期时间,要使用绝对时间,主从时钟需保持一致。
主从模式的缺点
需手动切换master,不支持横向扩展解决写压力及大数据量缓存。
哨兵Sentinel
sentinel节点负责监控master与slave的健康状态并进行故障检测和转移。并通知客户端
sentinel定期向master-slave发送心跳信号(ping),如果master-slave在指定时间没有响应信号,则代表当前sentinel认为该master主观下线。 当指定数量(一般过半)的sentinel都认为该实例主观下线,则该实例就被确认为客观下线,这时候sentinel就会选择一个从节点作为新的主节点,并将其切换到主节点状态。通知客户端新的master的地址,以确保客户端可以重连。
为什么要部署多个sentinel节点
检测master状态,防止误判。
master选举
与master节点的断开时间长短(只是做排除)--->优先级(越小越优,0不参与)---->offset(越大越优)--->运行id(越小越优)
- sentinel会判断slave节点与master节点断开时间的长短,如果超过指定值(down-after-milliseconds * 10),则会排除该slave节点。
- 再判断slave节点的slave-priority值,越小优先级越高,如果是0则永不参与选举。
- 如果slave-prority一样,则判断slave节点的offset值,越大说明数据越新,优先级越高。
- 最后是判断slave节点的运行id大小,越小优先级越高。
master切换流程
- sentinel给备选的slave节点发送slaveof no one指令,让其成为新的master。
- sentinel给其他的slave发送指令:slaveof 192.168.150.101 7002(master地址),让这些slave成为新master的从节点,并开始从master同步数据。
- sentinel将故障节点标记为slave,当故障节点恢复后会自动成为新master的从节点。
redis支持各种数据结构的存储,利用主从模式进行数据的备份。性能很高,所用操作都是原子性的。
sentinel 如何避免脑裂
配置master至少写入slave的数量
如果master长时间无法得到所有从节点的响应,
Redis Cluster
使用原因:缓存的数据量太大、并发量太大
主从复制和哨兵集群不支持横向扩展来缓解写压力和解决缓存数据量过大的问题
分片集群
- 在一个分片集群中,允许有多个master的存在,每个master存储不同的数据,且每个master下可以有多个slave节点;
- master之间也会通过ping检测彼此健康状态;
- 客户端访问任意的集群,最终都会被转发到正确节点。
Redis切片集群是部署多台Redis主节点,这些节点平等,同时提供读写操作,缓存的数据相对均匀的分布在这些Redis实例上。客户端的请求通过路由规则转发到目标master节点上。
redis 集群可以进行动态的扩容缩容。具备主从复制,故障转移的功能。
Redis 集群是去中心化的,各个节点通过Gossip协议进行通信,共有16384个hash槽。
哈希槽分区,对每个要存储的key计算CRC-16校验码,然后对该校验码对(2^14)16384取模,得到的值是可以要存储的hash槽。通过hash槽找到对应的redis节点。
客户端会缓存hash槽与节点的对应关系,当发送的master节点不是该hash槽的负责节点时,会返回重定向错误,客户端会更新缓存里的hash槽分配信息。解耦了数据和节点之间的关系,提升了集群的横向扩展性和容错性。
hash槽为什么是16384,2^14次方
避免更新hash槽对应关系时的信息太大,redis最多也就1000个主节点,16384足够用了。使用bitmap存储hash槽和节点对应信息。
redis cluster 重新分配hash槽
通过命令行分配,cluster addslots cluster setslot
扩容缩容期间如何提供服务
ASK重定向和MOVED重定向
ASK重定向是临时的重定向,MOVED会更新缓存里的哈希槽分配信息。
Redis集群节点之间的通信
各节点通过gossip协议来进行通信,redis cluster中内置了sentinel协议,PFAIL相当于主观下线,FAIL相当于客观下线。PING\Pong相互探测健康状态。