来说说缓存穿透、缓存击穿、缓存雪崩都是什么?怎么解决?
大量的这种请求,最终会导致数据库压力剧增,最终就会将数据打垮,若是这个数据库是核心数据库,那么其他所有依赖这个库的接口都会报错。
例如,每次请求的参数都是 id,而 id 是我们数据库里的自增主键,但是请求过来的参数要么是-1 这种,要么就是特别大的一个数,反正就是不存在的数据。
=============================================================================
那么如何解决缓存穿透呢?
首先最基本的就是要做参数校验,非法的参数就直接 return,连缓存层都到不了。
当请求的数据在穿过 Redis 后,数据库也返回空,这样的数据也可以存入到缓存中,然后过期时间可以设置一个比较短的时间,这样能够在一定程度上保障后端数据库的安全。
可以使用 Redis 的布隆过滤器,这个工具可以有效的防止缓存穿透的发生,我们可以将一个参数是否存在保存为一个 boolean 值,然后需要一个 bit 就可以存储,这样的数据压缩到一个数据结构中,就是布隆过滤器的原理。即节省存储空间,又能达到效果。
===========================================================================
我们在 Redis 存储的数据,主要是缓存的效果,目的是为了解决 DB 的压力,所以一些热点数据,都是先从缓存中获取的,当缓存中不存在的时候再从 DB 中获取然后再存入缓存。
但是如果一个高频的热点数据,在失效的一瞬间,它的大量请求就会直接打到 DB 上,这样在 DB 还没有返回数据给 Redis 的时候,DB 承受了热点请求的压力,就好像缓存是一个水桶,然后突然水桶破了一个洞,直接冲垮了后面的堤坝(DB)。
=============================================================================
造成缓存击穿的原因是,在同一时刻从数据库中获取了大量数据,并且设置了相同的过期时间,这些缓存就会在同一时刻失效,这样就造成了缓存击穿的问题。
解决方案
一些热点的数据,我们可以设置永不过期;或者是在访问数据的时候延长过期时间。
**也可以用分布式锁,来锁住数据,保证同一时间只有一个线程能够获取数据,其他请求获取不到数据,只能等待,但是在高并发的场景下,这种方案,体验不太好,
并且分布式锁的压力也会特别大**。
===========================================================================
Redis 中存储了很多的数据,但是有时候这些数据会出现,在同一个时刻批量过期的情况,因为有可能这些数据是批量插入的,所以他们的过期时间就会都在同一个时间。
正好在这个批量数据过期的时间点,大量的请求过来了,因为缓存数据过期了,所以没有命中缓存,直接请求到了数据库中。数据库的压力突然剧增,甚至有可能直接撑不住挂掉。然后有可能 DBA 会紧急重启 DB,但是刚一恢复,新的请求立马又把 DB 打垮了。
也有可能就是 Redis 挂了,缓存都不能用了,请求也是直接打到了 DB 上,然后 DB 也是扛不住压力,直接挂掉。再恢复,再挂掉。
Redis 中同一时刻大量的 Key 过期,那一瞬间和 Redis 不存在一样,还有 Redis 真的挂了的情况,这对服务和 DB 来说是灾难性的问题。
评论