一、缓存带来的回报
- 高速读写。
- 降低后端负载:后端服务器通过前端缓存降低负载;业务端使用 Redis 降低后端 MySQL 负载等。
二、缓存带来的代价
- 数据不一致。缓存层和数据层有时间窗口不一致,和更新策略有关。
- 代码维护成本。原本只需要读写 MySQL 就能实现功能,但加入了缓存之后就要去维护缓存的数据,增加了代码复杂度。
- 堆内缓存可能带来内存溢出的风险影响用户进程,如 ehCache、loadingCache。
三、堆内缓存和远程服务器缓存 Redis 的选择
- 堆内缓存一般性能更好,远程缓存需要套接字传输。
- 用户级别缓存尽量采用远程缓存。
- 大数据量尽量采用远程缓存,服务节点化原则。
四、什么是缓存雪崩?你有什么解决方案来防止缓存雪崩?
如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落在数据库上,造成了缓存雪崩。
由于原有缓存失效,新缓存未到期间所有原本应该访问缓存的请求都去查询数据库了,而对数据库 CPU 和内存造成巨大压力,严重的会造成数据库宕机。
五、你有什么解决方案来防止缓存雪崩?
1、加锁排队
mutex 互斥锁解决,Redis 的 SETNX 去 set 一个 mutex key,当操作返回成功时,再进行 load db 的操作并回设缓存;否则,就重试整个 get 缓存的方法。
2、数据预热
缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题。
用户直接查询事先被预热的缓存数据,可以通过缓存 reload 机制,预先去更新缓存,再即将发生大并发访问前手动触发加载缓存不同的 key。
3、双层缓存策略
C1 为原始缓存,C2 为拷贝缓存,C1 失效时,可以访问 C2,C1 缓存失效时间设置为短期,C2 设置为长期。
4、定时更新缓存策略
时效性要求不高的缓存,容器启动初始化加载,采用定时任务更新或移除缓存。
5、设置不同的过期时间
让缓存失效的时间点尽量均匀
六、什么是缓存穿透?
缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到对应 key 的 value,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请求就绕过缓存直接查数据库。
七、你有什么解决方案来防止缓存穿透?
1、缓存空值
如果一个查询返回的数据为空(不管是数据不存在,还是系统故障)我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。 通过这个直接设置的默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库
2、采用布隆过滤器 BloomFilter
将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力。优势占用内存空间很小,bit 存储。性能特别高。
八、Redis 有哪些特性?
- 丰富的数据类型
- 可用于缓存,消息按key设置过期时间,过期后自动删除 setex set expire 时间
- 支持持久化方式 rdb 和 aof
- 主从分布式,redis 支持主从支持读写分离 redis cluster,动态扩容方式
九、你用过 Redis 的哪几种特性?
- 用 sorted Set 实现过排行榜项目
- 用过期 key 结合 Spring Boot Cache 实现过缓存存储
- redis 实现分布式环境 seesion 共享
- 用布隆过滤器解决过缓存穿透
- redis 实现分布式锁
- redis 实现订单重推系统