谈谈缓存的优化

Posted 中年男子王二蛋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谈谈缓存的优化相关的知识,希望对你有一定的参考价值。


日常的开发过程中,缓存虽然已经作为一个必不可少的中间件存在于各个业务逻辑之中,分享一下怎么优化对缓存的使用。


概念

缓存雪崩

  • 因为数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。

  • 解决思路:加锁计数(即限制并发的数量,可以用semphore)或者起一定数量的队列来避免缓存失效时大量请求并发到数据库。但这种方式会降低吞吐量。分析用户行为,然后失效时间均匀分布。或者在失效时间的基础上再加1~5分钟的随机数。如果是某台缓存服务器宕机,则考虑做主备。


缓存穿透

  • 查询数据在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库中查询。

  • 解决思路:如果查询数据库也为空,直接设置一个默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库。设置一个过期时间或者当有值的时候将缓存中的值替换掉即可。可以给key设置一些格式规则,然后查询之前先过滤掉不符合规则的Key。


缓存并发

  • 如果网站并发访问高,一个缓存如果失效,可能出现多个进程同时查询DB,同时设置缓存的情况,如果并发确实很大,这也可能造成DB压力过大,还有缓存频繁更新的问题。

  • 解决思路:对缓存查询加锁,如果KEY不存在,就加锁,然后查DB入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入DB查询。


缓存预热

  • 目的就是在系统上线前,将数据加载到缓存中。

  • 解决思路:数据量不大的话,在系统启动的时候直接加载。自己写个简单的缓存预热程序。


实践

首先我们要做的是将访问最为频繁的数据缓存起来,这一步就是为了避免DB的压力过大而进行的处理,接着我们还需要设计一个定时器去定期维护这个数据,也即是通常所讲的补偿机制,防止因为某种未知错误的产生导致缓存没有及时更新。


一般来说做完上面两步,基本上可以满足日常的访问请求了,就算是临时因为异常导致缓存不可用也可以由DB临时进行支撑,但是如果真的遇到了访问量很大的业务,我们是需要避免DB被直接访问的,这就是要说到的缓存穿透和缓存雪崩的处理。一般来说缓存穿透最终是会导致缓存雪崩,只是时间问题。为了避免出现这种情况,我们会在业务逻辑中使用分布式锁来确保如果访问的KEY不存在,仅获取到锁的请求访问到DB将数据回写到缓存里,其他未获取到锁的请求要么进行等待数据回写再获取,要么直接放弃获取。





中年男子王二蛋

吐槽、闲聊,偶尔说点儿正经事


支持一下,点击下方在看】

以上是关于谈谈缓存的优化的主要内容,如果未能解决你的问题,请参考以下文章

面试官:谈谈你是怎么理解缓存的?

谈谈我理解的Http缓存机制

谈谈浏览器的缓存过期时间

谈谈Redis的SETNX

谈谈ASP.NET Core中的ResponseCaching

面试官:谈谈浏览器缓存DNS缓存CDN缓存是什么?