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

Redis是一个非关系型数据库,相对于其他数据库而言,它的查询速度极快,且能承受的瞬时并发量非常的高。所以常常被用来存放网站的缓存,以减少主要数据库(如mysql)的服务器压力。
Redis之缓存雪崩、缓存击穿和缓存穿透
使用Redis作为缓存到时候,经常会出现缓存雪崩、击穿和穿透的问题。这几个经典问题是什么?又该如何解决?
缓存雪崩
缓存雪崩是大量Key同时失效,对这些Key的请求会到数据库上,同样会导致数据库压力过大甚至挂掉。
电商平台一般会对数据进行缓存,如果所有首页的Key失效时间都是12小时,中午12点刷新,零点有个秒杀活动大量用户涌入,假设当时每秒 6000 个请求,本来缓存在可以扛住每秒 5000 个请求,但是缓存当时所有的Key都失效了。此时 1 秒 6000 个请求全部落数据库,数据库必然扛不住,会报警,而DBA反应不过来可能会重启数据库,但是数据库立马又被新的流量给打死了。
解决方案:让Key的失效时间分散开,可以在统一的失效时间上再加一个随机值,或者使用更高级的算法分散失效时间。
缓存穿透
程序在处理缓存时,一般是先从缓存查询,如果缓存没有这个key获取为null,则会从数据库中查询,并设置到缓存中去。那查询一个一定不存在的数据值,需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
简单来说,就是发起了一个查询操作,这个值缓存和数据库中都没有,这样就会来回的执行这一套流程,读取redis,发现没有然后连接数据库,发现也没有,从而造成缓存穿透。
解决方法:可以在系统层面加一层过滤,将系统认为非法的key进行一次拦截,直接返回给客户端错误信息。
缓存击穿
缓存击穿是针对缓存和数据库中都没有的数据。当Key失效后突然涌入大量的请求,都会请求到DB,导致数据库压力过大而崩溃。
这个问题的解决办法就是:
1、设置热点Key,自动检测热点Key,将热点Key的过期时间加大或者设置为永不过期,或者设置为逻辑上永不过期。
2、加互斥锁。当发现没有命中Redis,去查数据库的时候,在执行更新缓存的操作上加锁,谁拿到锁谁去更新,同时在拿到锁之后先从缓存再获取一次如果有就返回,没有就查库然后更新。(双重校验)

猜你喜欢

转载自blog.51cto.com/1086869/2451308