八股学习 Redis
- 使用场景
- 常见问题
- 问题1、2
- 示例场景
- 缓存穿透
- 解决方案一
- 解决方案二
- 问题3
- 示例场景
- 缓存击穿
- 解决方案
- 问题4
- 示例场景
- 缓存雪崩
- 解决方案
- 问题5
- 示例场景
- 双写一致性
- 强一致方案
- 允许延时一致方案
- 问题6
- RDB方式
- AOF方式
- 两种方式对比
- 问题7
- 示例场景
- 惰性删除
- 定期删除
使用场景
缓存:穿透、击穿、雪崩、双写一致、持久化、数据淘汰、淘汰策略;
分布式锁:setnx、redisson;
计数器、保存token、消息队列、延迟队列:数据类型;
常见问题
-
什么是缓存穿透,怎么解决?
-
什么是布隆过滤器?
-
什么是缓存击穿,怎么解决?
-
什么是缓存雪崩,怎么解决?
-
Redis双写问题?
-
Redis作为缓存如何实现持久化?
-
Redis的数据过期策略有哪些?
-
Redis的数据淘汰策略有哪些?
-
Redis分布式锁如何实现?
-
Redis实现分布式锁如何合理的控制锁的有效时长?
-
Redis集群有哪些方案?
-
什么是 Redis 主从同步?
-
使用的Redis是单点还是集群?哪种集群Redis分片集群中数据是怎么存储和读取的?
-
Redis集群脑裂
-
怎么保证Redis的高并发高可用?
-
用过Redis的事务吗?事务的命令有哪些?
-
Redis是单线程的,但是为什么还那么快?
-
…
问题1、2
缓存穿透、布隆过滤器
示例场景
缓存穿透
查询一个不存在的数据,mysql查不到,因此不会直接写入,导致频繁查询数据库;
解决方案一
缓存空数据,即使查询返回数据为空,也仍把空结果缓存;
优点:简单;
缺点:内存消耗,可能导致不一致问题;
解决方案二
布隆过滤器:
作用:检索一个元素是否在集合中;
优点:内存占用少,没有多余key;
缺点:实现相对复杂,存在误判;
问题3
缓存击穿
示例场景
缓存击穿
给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮;
解决方案
互斥锁
优点:强一致;
缺点:性能差;
逻辑过期
优点:高可用,性能优;
缺点:不能保证数据绝对一致;
问题4
缓存雪崩
示例场景
缓存雪崩
指在同一时间段大量的缓存key同时失效或者Redis宕机,导致大量请求到达数据库,带来巨大的查询压力;
解决方案
- 给不同的key的TTL添加随机值;
- 利用Redis集群提高服务可用性:哨兵模式、集群模式;
- 给缓存业务添加降级限流策略:ngxin或spring cloud gateway
- 给业务添加多级缓存:Guava或者Caffeine
问题5
示例场景
双写一致性
双写一致性
当修改了数据库的数据,也要同时更新缓存的数据,缓存数据于数据库数据要保持一致;
强一致方案
Redisson提供的读写锁
共享锁:读锁readLock,加锁后,其他线程可以共享读操作;
排它锁:独占锁writeLock,加锁后,阻塞其他线程读写操作;
允许延时一致方案
MQ中间件:更新数据后,通知缓存删除;
canal中间件:监听binlog数据更新缓存,不需要修改业务代码;
问题6
Redis持久化
RDB方式
bgsave开始时会fork主进程得到子进程,子进程 (不是子线程) 会共享主进程的内存数据,完成fork后读取内存数据并写入RDB文件;
fork采用的是copy-on-write技术
- 当主进程执行读操作时,访问共享内存;
- 当主进程执行写操作时,则会拷贝一份数据,执行写操作;
AOF方式
AOF全称为Append Only File(追加文件),Redis处理的每一个读写命令都会记录在AOF文件中,可以看作是命令日志文件;
需要注意的是,AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF:
AOF命令的记录频率也可以通过redis.conf文件来配置:
因为是记录命令,AOF文件会比RDB文件大的多。而且AOF会记录对同一个key的多次写操作,但只有最后一次写操作才有意义。通过执行bgrewriteaof命令,可以让AOF文件执行重写功能,用最少的命令达到相同效果;
Redis也会在触发阈值时自动去重写AOF文件,阈值也可以在redis.conf中进行配置:
两种方式对比
RDB和AOF各有优缺点,如果对数据安全性要求较高,在实际开发中往往结合两者来使用;
问题7
Redis数据过期策略
示例场景
Redis对数据设置数据的有效时间,数据过期以后,就需要将数据从内存中删除掉。可以按照不同的规则进行删除,这种删除规则就被称之为数据的删除策略(数据过期策略)。
惰性删除
设置该key过期时间后,我们不去管它,当需要该key时,我们在检查其是否过期,如果过期,我们就删掉它,反之返回该key;
优点:对CPU友好,只会在使用该key时才会进行过期检查,对于很多用不到的key不用浪费时间进行过期检查;
缺点:对内存不友好,如果一个key已经过期,但是一直没有使用,那么该key就会一直存在内存中,内存永远不会释放;
定期删除
每隔一段时间,我们就对一些key进行检查,删除里面过期的key(从一定数量的数据库中取出一定数量的随机key进行检查,并删除其中的过期key)。
定期清理有两种模式:
- SLOW模式:定时任务,执行频率默认为10hz,每次不超过25ms,以通过修改配置文件redis.conf的hz 选项来调整这个次数;
- FAST模式:频率不固定,但两次间隔不低于2ms,每次耗时不超过1ms;
优点:可以通过限制删除操作执行的时长和频率来减少删除操作对 CPU 的影响。另外定期删除,也能有效释放过期键占用的内存。
缺点:难以确定删除操作执行的时长和频率。
Redis的过期删除策略:惰性删除+定期删除两种策略进行配合使用