项目中Redis常见的一些问题(缓存穿透,缓存雪崩,内存耗尽等)
缓存穿透
缓存穿透是指查询一个不存在的数据,导致每次请求查询这个不存在的数据 都会转发到数据库,可能导致数据库崩溃
通常都会用布隆过滤器来解决它
布隆过滤器
布隆过滤器主要是用于检索一个元素是否在一个集合中。
它的底层主要是先去初始化一个比较大数组,里面存放的二进制0或1。在一开始都是0,当一个key来了之后经过3次hash计算,找到对应的数据的下标然后把数组中原来的0改为1,这样的话,三个数组的位置就能标明一个key的存在。
它的缺点是可能会产生一定的误判,我们一般可以设置这个误判率为5%,如果想要更低的误判率就得增加数组的长度
缓存雪崩
缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到数据库,数据库瞬时压力过重崩溃
解决方法:
- 在原有的失效时间基础上增加一个随机值,使得过期时间分散一些。这样每一个缓存的过期时间的重复率就会降低
- 设置二级缓存。二级缓存指的是除了 Redis 本身的缓存,再设置一层缓存,当 Redis 失效之后,先去查询二级缓存。例如可以设置一个本地缓存,在 Redis 缓存失效的时候先去查询本地缓存而非查询数据库
缓存击穿
缓存击穿:大量的请求同时查询一个 key 时,此时这个 key 正好失效了,就会导致大量的请求都落到数据库。缓存击穿是查询缓存中失效的 key,而缓存穿透是查询不存在的key。
解决方法:
加互斥锁。在并发的多个请求中,只有第一个请求线程能拿到锁并执行数据库查询操作
缓存预热
系统上线时,缓存内还没有数据,如果直接提供给用户使用,每个请求都会穿过缓存去访问底层数据库,如果并发大的话,数据库可能直接崩溃,因此我们需要在上线前先将数据库内的热点数据缓存至Redis内再提供出去使用,这种操作就成为"缓存预热"
解决方案:
1.如果数据量不大,可以在项目启动的时候自动进行加载;
2.定时刷新缓存;
缓存降级
当访问量剧增,服务出现问题时,仍然需要保证服务还是可用的,即使是有损部分其他服务,仍然需要保证主服务可用。可以将其他次要服务的数据进行缓存降级,从而提升主服务的稳定性
Redis的内存耗尽
如果达到设置的上限,Redis的写命令会返回错误信息(但是读命令还可以正常返回)。
配置内存淘汰策略来解决这个问题
内存淘汰策略有哪些?
LRU是最近最少使用页面置换算法(Least Recently Used),也就是首先淘汰最长时间未被使用的页面
LFU是最近最不常用页面置换算法(Least Frequently Used),也就是淘汰一定时期内被访问次数最少的页面
Redis如何做内存优化?
充分利用Redis的丰富的数据类型,因为通常情况下很多小的Key-Value可以用更紧凑的方式存放到一起。
尽可能使用散列表(hashes),散列表使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面