欢迎关注头条号:老顾聊技术

精品技术文章分享,知识的组装工


目录

  1. 前言
  2. 方案一
  3. 方案二
  4. 方案三
  5. 方案四

前言

上一文章中,我们提到可以利用锁机制防止缓存失效后,对后台数据库进行大量的请求,导致数据库崩溃。

加锁的原理其实就是只让一个请求访问数据库获取数据,阻塞其他请求让他们等待。老顾这里就用伪代码的方式进行介绍。看看我们小伙伴有没有自己想过相同的方案,他们的优缺点。

方案一

此方案确实能够保证同一时刻只有一个请求执行getGoodsInfo这个方法,但会有个严重的问题,也就是如果缓存有数据,同一时刻也会只有一个请求获取数据,其他请求都需要排队等待,这样系统的吞吐量会很低,此方案不可取。

方案二

这种方案就解决了系统吞吐量的问题,缓存数据存在时,所有请求不需要排队阻塞,直接从缓存读取数据返回。但会存在一个问题。大量请求在发现缓存没有数据时,会在【步骤三】加锁这边阻塞住,但一个请求从数据库读取数据后,在设置到缓存。其他请求还会在从数据库读取数据,在设置到缓存。虽然不会把数据库搞崩溃,因为每次就一个请求过来;但大量请求都做了同样的事情,根本没有必要每个请求都要从数据库中读取数据;只要第一个请求读取后,设置到缓存中,其他请求直接到缓存获取就行了。

方案三

此方案就解决了方案二的问题,双重判断是否缓存存在数据。在第一个请求从数据库查询出数据,设置到缓存中,释放锁;第二个请求进来,又先从缓存中获取数据,数据存在直接返回,这样就避免了方案二的问题。

我们再深入看一下,如:一共50个请求,在双重判断时,第一个请求去数据库查询并更新缓存数据,剩下的49个请求则是依次排队取缓存中取数据.这样最后的请求会时间很长,体验不是很好。

方案四

此方案利用了重入锁中的tryLock()方法,此方式尝试获取锁,如果获取不到就休息100ms,然后再发起获取数据流程。这样的话 第一个请求获取数据后,设置到缓存中后;其他的线程就不需要排队获取缓存中的数据了,极大了提升了用户的体验。

老顾引申一下,很多小伙伴在设计出方案后,不会仔细琢磨方案存在的隐含问题,此问题会不会影响到业务,有没有更好的方案?多思考才能比别人拿出更好的方案。


-End-

如有收获,请帮忙转发,您的鼓励是作者最大的动力,谢谢!

10几年的经验实战分享

相关微服务,分布式,高并发,高可用,企业实战,干货等原创文章正在路上

欢迎关注头条号:老顾聊技术

精品技术文章分享,知识的组装工

1.《如何防止缓存击穿 如何防止qq自动缓存》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《如何防止缓存击穿 如何防止qq自动缓存》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/keji/3264801.html