面试宝典(2)——缓存篇(Redis)
1.Redis的主要用途有哪些?
- 缓存
- 分布式锁:setnx,redisson
- 消息队列,延迟队列
2.什么是缓存穿透?
查询一个不存在的数据,数据库查询不到,同时也不会写入缓存,这就会导致每次查询都会去请求数据库。
解决方案一:缓存空数据,查询返回的数据为空,仍把这个空结果呢进行缓存。
优点:简单
缺点:消耗内存,可能会发生数据不一致问题。
解决方案二:布隆过滤器
布隆过滤器可以用于检索一个元素是否在集合中。
优点:内存占用少,没有多余的key
缺点:实现复杂,存在误判
3.什么是缓存击穿?
概念:当某一个热点Key设置了过期时间,当Key过期时,恰好这个时间点过来大量请求,将数据库压倒。
缓存击穿通常发生在缓存中设置了过期时间,而在该数据过期后,大量请求同时访问该数据的情况下。
解决方案一:互斥锁,互斥锁可是实现强一致性,性能略差。
解决方案二:设置逻辑过期。对于缓存数据,不设置过期时间,但是在缓存数据中设置逻辑过期。这种方案属于高可用,性能较优,但是逻辑过期实现的是最终一致。当业务允许短暂的不一致时,可以使用逻辑过期。
4.什么是缓存雪崩?
缓存雪崩是指在同一时段内大量缓存的key同时失效
,或者Redis服务宕机
,导致大量的请求同时到达数据库,从而导致数据库承受大量压力。
解决方案:
- 给不同的key设置不一样的TTL时间,或者设置指定范围内的随机值
- 利用Redis集群提高服务的可用性,比如
哨兵模式
,集群模式
- 给业务添加降级限流策略,比如
nginx
,Spring cloud gateway
- 给业务添加多级缓存,比如
Guava
或者Caffeine
5.Redis缓存的双写一致性
双写一致性:当修改了数据库的数据时要同步更新缓存数据,缓存要和数据库保持一致。
1.采用延时双删
的策略进行同步
删除缓存——>修改数据库——>延时删除缓存
延时双删依然存在脏数据的分险,做不到绝对的强一致。
2.采用互斥锁
,可以实现强一致
共享锁:读锁readLock,加锁之后,其他数据可以共享读操作,写操作则互斥。共享锁可以实现最终一致性。
排它锁:独占锁writeLock,加锁之后,阻塞其他线程读写操作,即读写均互斥,排它锁可以保证强一致性。
Redisson提供了读写锁的功能: