美文网首页
缓存的三个问题

缓存的三个问题

作者: ssochi | 来源:发表于2021-01-21 09:35 被阅读0次

这篇文章主要想讲讲缓存的三个问题:

  • 缓存穿透
  • 缓存击穿
  • 缓存雪崩

不得不说,这三个名称取的是波澜壮阔。单是听它的名字就让人不由的擦一把冷汗。
在日常业务中要是不注意这三个问题,那就得时刻做好跑路的准备。

缓存穿透

在日常业务中我们常常会对数据库的返回值进行缓存。如果数据库返回了空值我们应该怎么做呢?
在大多数并发不够大的场景下,对空值不做处理也不会发生什么事故。
而如果并发量大了,大量的空值由于没有被缓存,就会直接访问数据库,进而导致数据库不堪重负。
这就叫缓存穿透。

解决办法

  • 直接将空值进行缓存。

这看起来是个不错的办法,但是如果空值很多,就会找出我们需要缓存很多空值,这带来了巨大的内存消耗。
因此我们在实际工作中,应当给空值缓存设置一个合理的过期时间。

  • 布隆过滤器

布隆过滤器的优点是节约内存开销。
但布隆过滤器只能获取个大概的情况,不能完全保证通过过滤器就获取不到空值。
同时布隆过滤器只能加不能减,因此如果有频繁的插入操作时,布隆过滤器效率就很低。

缓存击穿

大多数缓存,我们都会设置一个过期时间。当缓存过期后,我们的服务会先访问数据库,再去更新缓存。
当有大量的缓存发现缓存过期,并尝试去访问数据库时,就产生了缓存击穿。

解决方法

  • 加锁

既然缓存击穿是由于大量服务都去访问数据库导致的,那么加上锁就能很好解决这个问题。
我们可以在服务进行数据库访问之前加上一个分布式锁,这样就能保证同时只会有一个服务去访问数据库。
在分布式锁的选择上,我们完全可以使用Redis来实现分布式锁,及时Redis实现的锁是AP的,可能出现数据丢失
但由于我们并不在意极端情况下锁的丢失,使用Redis锁可以说是很好的选择。

  • 不过期的缓存

我们可以不设置缓存的过期时间,在缓存的value中写入上次的更新时间。
这样当有服务发现缓存已经过期,就会用SetNX去更新过期时间,然后再去访问数据库,最后再更新缓存。
而别的服务,就读到了旧的缓存值。
这种方法存在一些问题

  1. 如果SetNX后,服务挂了,那么在之后的很长一段时间,缓存都处于一个过期值
  2. 由于没有过期时间,那么Redis的内存淘汰机制就失效了。因此只有热点的key,我们才能使用这种机制。
  3. 这种机制下,服务是可能读到过期的缓存的,因此如果业务对一致性要求高,就不能用这种机制。

缓存雪崩

在一段时间内,如果出现大量的缓存过期,那么就会出现缓存雪崩。
这是因为缓存雪崩会导致大量的服务去访问数据库,进而导致数据库不堪重负。

解决方法

  • 加锁
  • 不过期的缓存
  • 随机的过期时间

如果我们对缓存过期时间设置一个随机的偏移,那么在很大程度上我们能解决缓存雪崩。

相关文章

网友评论

      本文标题:缓存的三个问题

      本文链接:https://www.haomeiwen.com/subject/xlyboktx.html