Redis之缓存穿透,缓存击穿和缓存雪崩

438 阅读3分钟

缓存穿透

缓存穿透是指大量请求频繁访问数据库中不存在的数据,从而导致数据库频繁执行查询操作,又因为数据库中不存在此数据,无法缓存到redis中,从而给服务器造成巨大的压力。

解决方案

1.对空值进行缓存:当大量请求频繁查询不存在的数据的时候,虽然数据不存在,但是我们可以将空值放到redis缓存中,让其后续的访问都从redis查询,从而减小数据库的压力,但是要注意给空值设置过期时间,最多不能超过五分钟。

2.设置可访问白名单:使用bitmaps类型定义一个可以访问的白名单,名单id作为bitmaps的偏移量,每次访问时和bitmaps里的id进行比较,如果id不在bitmaps里面,则进行拦截不允许访问。

3.采用布隆过滤器

4.进行实时监控:当发现redis命中率急速降低时,可以排查访问对象,设置访问黑名单。

缓存击穿

某个被频繁访问的热点数据,在一瞬间失效,从而导致大量对该数据的请求直达数据库,瞬间对数据库造成巨大的压力,使数据库挂掉。

解决方案

1.预先设置热点数据,在redis高峰访问之前,把一些热点数据提前存入到redis里,延长过期时间。

2.实时调整:监控redis,实时调整热门数据的过期时常。

3.使用锁机制:当数据缓存失效时,我们不立刻去查询数据库,而是先设置一个排他锁(setex),然后再去数据库中查询数据,此时其他的请求无法获取到锁,当我们从数据库中查到数据后再回写到缓存中,然后再删除这个排他锁,其他请求就又可以从缓存中拿到数据了。但是这样会降低效率。

缓存雪崩

缓存雪崩是指大量缓存失效,从而导致大量对应数据的请求短时间内直达数据库,对数据库造成巨大的压力,使数据库挂掉。

解决方案:

1.使用多级缓存架构:nginx缓存+redis缓存+其他缓存等。

2.使用锁或者队列:使用锁或者队列避免大量请求对数据的并发访问,不适用于高并发情况。

3.设置过期标识更新缓存:设置一个缓存过期的提前量,当这个提前量过期时会触发另外的线程去更新实际的key的缓存

4.均匀分配过期时间,当我们给key设置过期时间时,可以在失效时间的基础上设置一个随机值,从而让不同的key的失效时间分散开,从而减少数据库的压力