redis理论学习:高可用
缓存击穿,穿透,雪崩
缓存击穿,redis里存的热点数据过期,导致访问全都打到了mysql身上
缓存穿透,redis和mysql里都找不到数据,直接穿透了存储系统
缓存雪崩,大量缓存同时过期,导致请求达到mysql身上
redis高可用
主从模式
主服务器可读可写,发生写操作同步给从服务器,从服务器只读,接收主服务器同步的写操作,没办法实现强一致性
哨兵集群
redis主从服务器宕机的时候要手动恢复,哨兵模式的话添加了一个哨兵进程,可以监控主从服务器,并且提供了主从节点故障转移的功能
切片集群
把redis切片,让数据分布到不同的服务器上,提高redis服务的读写性能
主从复制
主从复制有三个模式:全量复制,基于长连接的命令传播,增量复制
主从服务器第一次同步的时候就采用全量复制,主服务器生成RDB文件并传输给从服务器。为了避免过多的全量复制,会允许一部分从服务器也可以对自己的从服务器进行全量复制
第一次同步完成后主从服务器会维护一个长连接,主服务器收到写操作后通过这个tcp连接同步到从服务器
如果网络断开就进行增量复制,把断开期间的写操作同步给从服务器。
通过repl_backlog_buffer这个环形缓冲区和replication offset这个标记来实现
环形缓冲区会保存最近的命令,master_repl_offset记录写的命令位置,slave_repl_offset记录从服务器获取的位置
如果从服务器缺失过多,已经不在buffer缓冲区了,就会全量复制
哨兵机制
如果主从复制里主服务器挂了,就没有服务器用于写操作,也没有服务器进行同步了,这时候就要人工切换,太麻烦了所以添加了一个哨兵机制:监测主节点是否存活,如果挂了就选一个从节点作为主节点
哨兵是一个特殊的redis进程
如何监控主节点是否真的挂了?
哨兵每隔一秒会向所有主从节点发送ping命令,如果收到响应就是正常运行
如果没收到响应就判断为主观下线
由哪个哨兵进行主从故障转移?
谁判断主节点客观下线,谁就是Leader候选者
候选者会向其他哨兵发送命令,然后其他哨兵进行投票,如果拿到半数以上的赞成票以及票数大于等于哨兵配置文件中的quorum值,就会称为leader
因为票数大于一半以上才能选出leader,所以哨兵最少也需要三个
主从故障转移过程是怎样的?
第一步判断:
- 先过滤掉网络连接不好的
- 根据节点优先级来排序,优先级可以根据硬件条件来设置
- 哪个最近复制,哪个靠前
- ID小的
第二步从节点指向新的主节点
向新的主节点发送slaveon升级,向其他节点发送slaveon指向新的主节点
第三步通知客户端主节点更换了
最后一步如果旧的主节点重新上线了,就让它作为从节点指向新的主节点
切片集群
通过数据分片和去中心化架构,突破单机redis的内存和性能瓶颈
如果我的数据有25G,但是内存最多也就5G,如果选择升级到32G内存成本有些大,可以把数据分成五个5G
数据分片机制
- 虚拟槽(Hash Slot):将全量数据划分为 16384 个槽位,每个键通过
CRC16(key) % 16384
计算所属槽位,实现数据均匀分布。- 示例:若集群有 3 个主节点,槽位分配可能为:
- 节点 A:0-5460
- 节点 B:5461-10922
- 节点 C:10923-16383
- 示例:若集群有 3 个主节点,槽位分配可能为:
- 去中心化结构:所有节点互联(PING-PONG 机制),通过 Gossip 协议交换集群状态(如节点存活、槽位分配)。
分布式锁
就是分布式场景下的锁,比如不同机器上的多个进程,去竞争同一项资源
一个好锁要有以下性质
- 互斥性:锁的目的就是保证同一时间只有一个可以访问该资源,所以要保证互斥性
- 抗死锁性:避免锁因为某些原因一直不释放,如果因为意外,也有兜底措施可以释放
- 对称性:同一个锁,上锁和解锁的都得是同一个程序,不能别的程序释放锁
- 可靠性:具有一定的异常处理和消灾能力
redis可以通过上面的命令实现添加过期时间的分布式锁,保证了锁的抗死锁性和互斥性
如何保证对称性?需要加上owner,释放锁都需要检查该锁owner是否为自己,但是因为操作不是原子的,可能存在检查owner到删除之间的时候,锁过期被其他程序抢到,但是却被删除的问题
所以需要加上lua保证分布式锁的对称性
最后可靠性就是依靠主从容灾和多机部署来解决