2024-03-18 06:38:57
Redis缓存穿透、击穿和雪崩是Redis缓存使用中常见的三种问题,它们各自有不同的特点和解决方案。
缓存穿透缓存穿透是指Redis中没有缓存数据,数据库中也没有对应的数据,业务系统每次都会绕过缓存服务器查询下游的数据库,缓存服务器完全失去了其应有的作用。
缓存穿透形成的原因,有可能是key写错了,也有可能是恶意攻击。缓存穿透会导致后端数据库负载加大,缓存层失去了应有的作用,高并发下可能会造成数据库的宕机。
执行流程如下图:
缓存空值:如果某个核酸点没有核酸检测物料,比如试管,可以在第一次问询防疫中心,如果都没有的情况下,就会在这个核酸点贴出公告,告知做核酸的人员,这样后面排队的人就不用苦苦等待了。对于数据缓存来说,如果在第一次查询时数据为空,就可以直接将null值缓存,但要设置一个较短的过期时间。这样,当db中有数据时,可以及时更新,或者利用mq发送异步消息,触发数据的Redis设置。
缓存空值流程如下图:
布隆过滤器(BloomFilter):一般核酸点,会有一个拿着喇叭的志愿者,当他告诉你没有物料时,你就没必要排队了。而缓存穿透也有很多情况,很多是恶意访问造成的,这些请求可能会随机生成很多key,如果使用空值处理,会在redis中生成很多垃圾数据,这时可以使用布隆过滤器来进行解决。布隆过滤器是一种比较巧妙的概率性数据结构,它可以告诉你数据一定不存在或可能存在。相比Map、Set、List等传统数据结构,布隆过滤器占用的内存少、结构更高效。对于缓存穿透,可以将查询的数据条件都哈希到一个足够大的布隆过滤器中,用户发送的请求会先被布隆过滤器拦截,一定不存在的数据就直接拦截返回了,从而避免下一步对数据库的压力。
布隆过滤器流程如下图:
缓存击穿是指当某一个key缓存过期时,突然有大并发量的请求同时访问这个key,这有可能会瞬间击穿缓存服务器而去直接访问数据库,让数据库处于高负载的情况。DB负载过大,就可能会造成后端服务器宕机。尤其是在秒杀、大促的情况下,并发请求量过大,而key刚好又过期,缓存key对应的key值,计算又比较复杂,重新缓存到数据库也需要一段时间,这时就可能会压垮后端数据库。
执行流程如下图:
异步定时更新(及时预防):可以安排一个志愿者,专门管理核酸、物料,一旦总部有了,马上调拨。放到项目中,可以设置一个定时任务来检查DB。一旦DB中有了数据,就及时放入缓存。如果遇到秒杀大促等高并发的场景,需要在缓存的key失效之前,重新进行缓存,相当于更新数据+延时。
分布式互斥锁:没有物料后,首先通知第一个做核酸的,然后询问防疫指挥进行调拨,并让志愿者进行喇叭通知,让其他排队的都进入到等待状态。在处理缓存时,通常使用一个互斥锁来解决缓存击穿的问题。简单来说,就是当Redis中根据key获得的value值为空时,先给它锁上;然后再从数据库进行加载,加载完毕后再释放锁。若其他线程也在请求该key时,发现获取锁失败,则先阻塞。
分布式互斥锁流程如下图:

缓存集中在一个时间内同时大量失效,就可能会发生大量的缓存穿透,此时查询都落在数据库上,造成数据库负载瞬间过高,严重影响性能,最后有可能导致数据库直接宕机。
为key设置不同的过期时间:避免所有的key在同一时间过期,可以给不同的key设置不同的过期进间。
为key设置不同的过期时间流程如下图:

给DB做集群部署:可以对DB搭建集群,进行分流。
给DB做集群部署流程如下图:
