缓存数据和数据库不一致
对于读写缓存,可以采用同步写回策略
对于只读缓存
其中先删除缓存值,再更新数据库的操作中,重试数据库更新是用消息队列来实现
其中先删除缓存值,再更新数据库的操作中,延迟双删是指执行删除的线程1在更新数据库后,sleep一段时间,让来读取这个数据的线程2读数据,发现缓存没有,然后从数据库中找到值更新过去,由于是并发执行的,这里线程2读到的可能是旧值,因此需要删除这个存到缓存的数据,然后sleep醒过来的线程1再进行删除线程2更新的缓存。这之后的线程就发现缓存中没有,去数据库读到最新值了。
缓存雪崩
缓存雪崩是指大量的应用请求无法在redis缓存中进行处理,紧接着大量请求发送给数据库层,数据库压力激增。
原因:
-
缓存中有大量数据同时过期,导致大量数据无法得到处理
解决方案:
1.避免给大量数据设置相同的过期时间,就算是业务要求有些数据时间相同,可以使用EXPIRE给每个数据 设置过期时间的时候,加上一个较小的随机数。
2. 服务降级,就是当业务访问的是非核心数据时,就暂停从缓存中查询这些数据,而是直接返回预定义信 息,空值,或错误信息。当业务访问的是核心数据时,就仍然允许查询缓存,如果需要访问数据库,也 允许
2. redis缓存实例发送故障宕机了,无法处理请求,大量请求堆积到数据库层
解决方法:
1.在业务系统中实现服务熔断,即业务应用调用缓存接口时,缓存客户端并不把请求发送给redis缓存实例,而是直接返回,等到redis缓存实例重启后,再运行请求发送到缓存实例。
2.请求限流,在业务系统的请求入口前端控制每秒进入系统的请求数,避免过多的请求被发送到数据库。
3.构建redis高可用缓存集群,主节点挂掉后,从节点替换主节点继续提供服务。
缓存击穿
缓存击穿就是大量的热点数据同时过期,导致大量请求访问到数据层
解决方法:对于访问特别频繁的数据可以不设置过期时间。或者提前预热,把热点数据重新存入,设置好过期时间。
缓存穿透
缓存穿透是指要访问的数据既不在 Redis 缓存中,也不在数据库中,导致请求在访问缓存时,发生缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据。
第一种方案:缓存空值或缺省值
第二种方案:使用布隆过滤器快速判断数据是否存在,避免从数据库查询数据。
布隆过滤器怎么工作的呢?
布隆过滤器由一个初值为0的bit数组和N个哈希函数组成,可以用来快速判断某个数据是否存在。
如何标记一个数存在:
-
首先,使用N个哈希函数对数据求哈希值,得到N个哈希值
-
把这N个哈希值对bit数组的长度取模,得到哈希值在数组中的对应位置
-
最后,把对应位置的bit位设置为1。
当需要查询这个数据时,我们就执行刚刚说的计算过程,先得到这个数据在bit数组中对应的N个位置,紧接着查看这N个位置的bit值,有一个不为1就说明数据库中不存在这个数据。
第三种方案,在请求入口的前端进行请求检测。