Redis分布式缓存

文章目录

  • 1. Redis持久化
    • 1.1 RDB持久化
    • 2.2 AOF持久化
  • 2. Redis主从
  • 3. Redis哨兵
  • 4. Redis分片集群

1. Redis持久化

1.1 RDB持久化

RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。快照文件称为RDB文件,默认是保存在当前运行目录。

RDB持久化在四种情况下会执行:

  • 执行save命令
  • 执行bgsave命令
  • Redis停机时
  • 触发RDB条件时
    Redis分布式缓存_第1张图片
    Redis分布式缓存_第2张图片
    这个命令执行后会开启独立进程完成RDB,主进程可以持续处理用户请求,不受影响
    在这里插入图片描述
    Redis分布式缓存_第3张图片

RDB原理
bgsave开始时会fork主进程得到子进程(复制页表),子进程共享主进程的内存数据。完成fork后读取内存数据并写入 RDB 文件。

fork采用的是copy-on-write技术:

  • 当主进程执行读操作时,访问共享内存;
  • 当主进程执行写操作时,则会拷贝一份数据,执行写操作。
    Redis分布式缓存_第4张图片

2.2 AOF持久化

AOF全称为Append Only File(追加文件)。Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文件。
Redis分布式缓存_第5张图片
AOF文件重写
Redis分布式缓存_第6张图片

RDB与AOF对比
Redis分布式缓存_第7张图片

2. Redis主从

全量同步:主从第一次建立连接时,会执行全量同步,将master节点的所有数据都拷贝给slave节点.
master判断一个节点是否是第一次同步的依据,就是看replid是否一致
Redis分布式缓存_第8张图片
完整流程描述:

  • slave节点请求增量同步
  • master节点判断replid,发现不一致,拒绝增量同步
  • master将完整内存数据生成RDB,发送RDB到slave
  • slave清空本地数据,加载master的RDB
  • master将RDB期间的命令记录在repl_baklog,并持续将log中的命令发送给slave
  • slave执行接收到的命令,保持与master之间的同步

增量同步
全量同步需要先做RDB,然后将RDB文件通过网络传输给slave,成本太高了。因此除了第一次做全量同步,其它大多数时候slave与master都是做增量同步。就是只更新slave与master存在差异的部分数据
Redis分布式缓存_第9张图片

repl_backlog文件:
这个文件是一个固定大小的数组,只不过数组是环形,repl_baklog中会记录Redis处理过的命令日志及offset,包括master当前的offset,和slave已经拷贝到的offset


主从同步可以保证主从数据的一致性,非常重要。
可以从以下几个方面来优化Redis主从就集群:

  • 在master中配置repl-diskless-sync yes启用无磁盘复制(直接写到网络而不是磁盘),避免全量同步时的磁盘IO。
  • Redis单节点上的内存占用不要太大,减少RDB导致的过多磁盘IO
  • 适当提高repl_baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步
  • 限制一个master上的slave节点数量,如果实在是太多slave,则可以采用主-从-从链式结构,减少master压力

小结
简述全量同步和增量同步区别?

  • 全量同步:master将完整内存数据生成RDB,发送RDB到slave。后续命令则记录在repl_baklog,逐个发送给slave。
  • 增量同步:slave提交自己的offset到master,master获取repl_baklog中从offset之后的命令给slave

什么时候执行全量同步?

  • slave节点第一次连接master节点时
  • slave节点断开时间太久,repl_baklog中的offset已经被覆盖时

什么时候执行增量同步?

  • slave节点断开又恢复,并且在repl_baklog中能找到offset时

3. Redis哨兵

Redis提供了哨兵(Sentinel)机制来实现主从集群的自动故障恢复。
Redis分布式缓存_第10张图片
哨兵的作用如下:

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

集群监控原理

Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令:

  • 主观下线:如果某sentinel节点发现某实例未在规定时间响应,则认为该实例主观下线

  • 客观下线:若超过指定数量(quorum)的sentinel都认为该实例主观下线,则该实例客观下线。quorum值最好超过Sentinel实例数量的一半。

集群故障恢复原理
一旦发现master故障,sentinel需要在salve中选择一个作为新的master,选择依据是这样的:

  • 首先会判断slave节点与master节点断开时间长短,如果超过指定值(down-after-milliseconds * 10)则会排除该slave节点
  • 然后判断slave节点的slave-priority值,越小优先级越高,如果是0则永不参与选举
  • 如果slave-prority一样,则判断slave节点的offset值,越大说明数据越新,优先级越高
  • 最后是判断slave节点的运行id大小,越小优先级越高。

当选出一个新的master后,该如何实现切换呢?
Redis分布式缓存_第11张图片
Sentinel的三个作用是什么?

  • 监控
  • 故障转移
  • 通知

Sentinel如何判断一个redis实例是否健康?

  • 每隔1秒发送一次ping命令,如果超过一定时间没有相向则认为是主观下线
  • 如果大多数sentinel都认为实例主观下线,则判定服务下线

故障转移步骤有哪些?

  • 首先选定一个slave作为新的master,执行slaveof no one
  • 然后让所有节点都执行slaveof 新master
  • 修改故障节点配置,添加slaveof 新master

搭建哨兵集群案例:

在Sentinel集群监管下的Redis主从集群,其节点会因为自动故障转移而发生变化,Redis的客户端必须感知这种变化,及时更新连接信息。Spring的RedisTemplate底层利用lettuce实现了节点的感知和自动切换。

  1. 引入依赖Redis分布式缓存_第12张图片
  2. 配置Redis地址:这里配置的是sentinel地址,它类似于nacos服务发现Redis分布式缓存_第13张图片
  3. 配置读写分离Redis分布式缓存_第14张图片

4. Redis分片集群

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

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

Redis分布式缓存_第15张图片
分片集群特征:

  • 集群中有多个master,每个master保存不同数据(基于槽的实现,key算出槽,再由该槽绑定master)
  • 每个master都可以有多个slave节点
  • master之间通过ping监测彼此健康状态
  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点

插槽原理
Redis会把每一个master节点映射到0~16383共16384个插槽(hash slot)上。

数据key不是与节点绑定,而是与插槽绑定。redis会根据key的有效部分计算插槽值,分两种情况:

  • key中包含"{}",且“{}”中至少包含1个字符,“{}”中的部分是有效部分
  • key中不包含“{}”,整个key都是有效部分

故障转移
当集群中有一个master宕机会发生什么呢?

  • 自动故障转移:该master关联的slave选一个出来
  • 手动故障转移:利用cluster failover命令可以手动让集群中的某个master宕机,切换到执行cluster failover命令的这个slave节点,实现无感知的数据迁移Redis分布式缓存_第16张图片

RedisTemplate访问分片集群Redis分布式缓存_第17张图片

你可能感兴趣的:(springcloud,缓存,redis,分布式)