Redis 使用场景
缓存穿透
查询一个不存在的数据,MySQL 查询不到数据也不会直接写入缓存,导致每次请求都查询数据库
解决方案一
缓存空数据,查询返回的数据为空,仍把这个空结果进行缓存
- 优点:简单
- 缺点:消耗内存,可能会发生不一致的问题
解决方案二
布隆过滤器
- 优点:内存占用较少,没有多余 key
- 缺点:实现复杂,存在误判
面试回答
缓存击穿
给某一个 key 设置了过期时间,当 key 过期的时候,恰好这个时间点有大量并发请求访问这个 key,这些并发的请求可能瞬间把 DB 压垮。
解决方案一
互斥锁
- 优点:强一致
- 缺点:性能差
解决方案二
逻辑过期
- 优点:高可用,性能优
- 缺点:不能保证数据的绝对一致
面试回答
缓存雪崩
同一时间段大量的缓存 key 同时失效或者 Redis 服务宕机,导致大量请求到达数据库,带来巨大压力。
解决方案
- 给不同的 key 的 TTL 添加随机值
- 利用 Redis 集群提高服务的可用性:哨兵模式、集群模式
- 给缓存业务添加降级限流策略:Nginx、Spring Cloud Gateway
- 给业务添加多级缓存:Guava、Caffeine
面试回答
双写一致性
当修改了数据库的数据时,也要同时更新缓存的数据,缓存和数据库的数据要保持一致。
解决方案一
延迟双删:有脏数据风险(了解)
解决方案二
最终一致性
异步通知
- 使用 MQ 中间件,更新数据之后,通知缓存删除
- 利用 Canal 中间件,不需要修改业务代码,伪装为 MySQL 的一个从节点,Canal 通过读取 binlog 数据更新缓存
强一致性
采用 Redission 提供的读写锁
- 共享锁:读锁 readLock,加锁之后,其他线程可以共享读操作
- 排他锁:也叫独占锁 writeLock,加锁之后,阻塞其他线程读写操作
持久化
RDB
RDB 全称 Redis Database Backup File,也被叫做 Redis 数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。让 Redis 实例故障重启后,从磁盘读取快照文件,恢复数据
两种方式
- save:由 Redis 主进程执行 RDB,会阻塞其他进程
- bgsave:开启子线程执行 RDB,避免主线程受到影响
RDB 执行原理
AOF
AOF 全称为 Append Only File。Redis 处理的每一个写命令都会记录在 AOF 文件,可以看做是命令日志文件。
RDB 与 AOF 对比
面试回答
数据过期策略
惰性删除
设置 key 过期时间后,不去管它,当需要该 key 时再去检查是否过期,若过期,则删掉,反之返回。
优缺点
定期删除
每隔一段时间,对一部分 key 进行检查,删除里面过期的 key
SLOW 模式
定时任务,执行频率默认 10hz,每次不超过 25ms,以通过修改配置文件的 hz 选项来调整
FAST 模式
执行频率不固定,但两次间隔不低于 2ms,每次耗时不超过 1ms
优缺点
Redis 采取的策略
惰性删除 + 定期删除结合使用