前言
缓存应该是技术人员最常见的一个词了,但是或许不是所有人都能准确的说出缓存本质是什么,又适用于什么情况,可能遇到哪些问题,应该怎么来解决。下面我就分三篇文章来给大家详细介绍下缓存相关的知识。疏漏不足之处,也请指正,不胜感激。
《缓存那些事之初识缓存》
《缓存那些事之缓存更新、失效以及内存淘汰策略》
《缓存那些事之常见问题与解决方案》
缓存问题与解决方案
缓存确实有千般好,可以有效提高我们系统的性能,但是同时也会带来一些问题,如果没有好好处理这些问题,就会给系统带来很多不可控的因素,下面我们来了解下缓存系统常见的问题以及如何来解决。
缓存穿透
缓存穿透是指用户查询的数据在数据库中不存在,这时候自然不会更新到缓存系统中,因此,每次查询这个不存在的数据的时候,我们都需要去数据库去查询,这也就失去了缓存的意义。另外黑客也可能利用这一点来进行攻击,例如频繁使用不存在的key(如非常大的id)来查询我们的应用,这就可能会导致数据库由于压力过大而宕掉。
解决方案
-
布隆过滤器:通过布隆过滤器把一定不存在的数据过滤掉,这样查询到我们数据库的就都是可能存在的数据,可以大大减少对数据库的查询压力。但是如果查询的数据是在我们允许的范围内,只是目前还是空值,那布隆过滤器也没办法解决,就需要用后面的方法了。
-
短缓存空结果:如果一个查询的结果为空,仍然把这个空结果进行缓存,但是和正常的数据的缓存时间不同,空结果的缓存时间需要设置得很短,避免后面有数据了之后仍然一直缓存着空数据。那么这里大家可能会问了,我设置一个很长的时间,然后新增数据后让缓存失效不就好了吗?事实上这里即使使用了合适的缓存更新策略也仍然应该设置较短的过期时间,因为我们不可能每次新增数据都去失效缓存。和更新数据不同,更新的时候我们一般需要去让缓存也失效,但是新增数据的时候,我们大概率不存在对应的空缓存,如果新增数据的时候也去让缓存失效,就会多出很多不必要的网络请求,所以新增的时候我们一般不会去让对应的缓存失效。
缓存雪崩
缓存雪崩是指因为某些原因,导致缓存在某一个时间内大规模失效,例如设置了同一个过期时间,或者缓存服务宕机了,这时候就会有大量的请求直接到数据库上面,数据库瞬时压力过重而挂了。
缓存服务宕机的情况我们这里先不讨论,这个主要是服务的高可用和服务降级的问题。我们来看看另一种情况如何来解决。
解决方案
- 随机过期时间:在原有过期时间上加上一个随机值,这样过期时间相对随机,避免缓存同时大规模过期。
- 加锁写缓存:缓存过期时,系统先获取锁,获取成功的才允许读数据库,并写入缓存,其他请求就都返回稍后重试或者直接sleep一小段时间然后重试原有逻辑。
- 提前过期:设置缓存的时候,在缓存的数据里加多一个字段,表示提前过期时间,这个过期时间比缓存真正过期的时间短。然后读缓存的时候,如果发现缓存里的提前过期时间到了,就去获取锁,获取到的请求读数据库,并写入缓存,同时更新提前过期时间和缓存过期时间,而其他没有获取到锁的请求就按读到的缓存数据正常往后面走逻辑,不再负责更新缓存。
缓存击穿
缓存击穿和缓存雪崩很像,缓存雪崩是同一时间大量缓存过期,导致数据库压力过大宕机了,而缓存击穿是指某一个热点key过期了,而这时候这个kye又有大量请求过来,就会给数据库带来巨大压力,导致数据库宕机。缓存击穿的解决方案可以采取缓存雪崩的后两个方案,这里就不赘述了。
Enjoy it !
如果觉得文章对你有用,可以赞助我喝杯咖啡~
版权声明
转载请注明作者和文章出处
作者: X先生
https://blog.csdn.net/u013314679/article/details/105664956