Redis 缓存穿透、缓存击穿、缓存雪崩的解决方案
一、缓存雪崩
缓存雪崩表示:指缓存同一时间大面积失效或缓存重启又或者第一次启用缓存的情况下,导致请求跳过缓存直接请求数据库,造成数据库短时间内承受大量请求而崩掉。
解决方案:
方案一
缓存数据的过期时间设置随机,防止同一时间到大量数据过期现象发生。
方案二
给每个缓存数据增加响应的缓存标记,记录缓存是否失效,如果缓存标记失效,则更新数据库缓存
优点:
数据在即将或已经失效的情况下,立刻重新从数据库取出数据进行缓存,避免后续请求直接请求数据库。
缺陷:
性能损耗较大,需要对缓存失效进行监听
方案三
缓存预热,主要是针对缓存重启或缓存第一次重启的情况下,在启用系统之前,先将数据放到缓存中,然后再启动系统,做到缓存预热。
方案四
互斥锁,表示查到一个缓存,发现这个缓存已经失效了,此刻将这个缓存键锁起来,再从数据库取数据,并将数据放入缓存中,再对锁进行释放。可以避免大量的请求对同一个键进行大量的操作,让大量的请求进行排队
二、缓存穿透
缓存穿透表示缓存中和数据库中都没有数据的情况下,导致所有的请求都落到数据库上,造成数据库短时间承受大量请求而崩掉。
缓存穿透的出现场景,一般为网络攻击导致缓存和数据库数据丢失。
解决方案
方案一
接口层增加校验,如用户鉴权校验、参数校验(id做基础校验),如id<1的直接拦截。
方案二
从缓存取不到数据,在数据库中也取不到数据,这时可以将key-value写为 key-null,存入缓存中,这样可以防止用户反对用同一个id办理攻击,让对key 的攻击失效,这样可以解决对同一个key的攻击问题进行解决。
方案三
采用布隆过滤器,将所有可能存在的数据哈气到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免对底层存储系统的查询能力。
三、缓存击穿
缓存击穿是指缓存中没有但数据库中数据(一般是缓存时间到期所致),这时由于并发用户特别多,同时读缓存没有读取到数据,又同时去数据库去数据,引起数据压力瞬间增大,造成过大压力。和缓存雪崩不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都到期,很多数据都查不到从而查数据库。
解决方案
方案一
设置热点数据永远不过期
方案二
加互斥锁