For investors
股价:
5.36 美元 %For investors
股价:
5.36 美元 %认真做教育 专心促就业
缓存技术的应用我们在前几期的文章中已经给大家介绍过很多次了,缓存雪崩和缓存击穿也是比较常见的一个缓存技术应用问题,下面我们就通过案例分析来了解一下,缓存雪崩和缓存击穿解决方法分享。
1、恐怖的缓存雪崩问题的解决方案
问题:缓存服务大量的资源全部耗费在访问redis和源服务无果,后自己被拖死,无法提供服务。
方案:相对来说,考虑的比较完善的一套方案,分为事前,事中,事后三个层次去思考怎么来应对缓存雪崩的场景。
事前:高可用架构。主从架构,操作主节点,读写,数据同步到从节点,一旦主节点挂掉,从节点跟上。
事中:多级缓存。rediscluster已经彻底崩溃了,缓存服务实例的ehcache的缓存还能起到作用。
事后:redis数据可以恢复,做了备份,redis数据备份和恢复,redis重新启动起来。
2、缓存穿透问题的解决方案
问题:缓存中没有这样的数据,数据库中也没有这样的数据。由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。
方案:有很多种方法可以有效地解决缓存穿透问题,常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法(我们采用的就是这种),如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,长不超过五分钟。
3、如何避免缓存击穿?
主动更新缓存:默认缓存是被动更新的。只有在终端请求发现缓存失效时,它才会去数据库查询新的数据。那么,如果我们把缓存的更新,从被动改为主动,也就可以直接绕开缓存风暴的问题了,在OpenResty中,我们可以使用ngx.timer.every来创建一个定时器去定时更新。
缺点:每一个缓存都要对应一个周期性的任务;而且缓存过期时间和计划任务的周期时间还要对应好,如果这中间出现了什么纰漏,终端就可能一直获取到的都是空数据
使用互斥锁:请求发现缓存不存在后,去查询DB前,使用锁,保证有且只有一个请求去查询DB,并更新到缓存。流程如下:
获取锁,直到成功或超时。如果超时,则抛出异常,返回。如果成功,继续向下执行。
再去缓存中。如果存在值,则直接返回;如果不存在,则继续往下执行如果成功获取到锁的话,就可以保证只有一个请求去数据源更新数据,并更新到缓存中了。
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。