redis 缓存问题 以及解决方案

缓存穿透

描述: 查询数据库中不存在的数据,高并发的情况下,压力集中在数据库
解决方案:

  • 1) 将空值Null也放入数据库,设置过期时间较短。
  • 2) 布隆过滤器

缓存雪崩

描述: 缓存中大量的key同时过期,导致请求直接到了数据库。
解决方案:

  • 1) 分开缓存的时间,避免同时有大量的key过期。

缓存击穿

描述: 某个key在即将过期时有大量的请求,当key过期时,所有的请求通过了缓存直接到达了数据库
解决方案:

  • 1) 缓存加锁,如果key不存在就加锁,然后查询数据库,其他相同请求,如果发现有锁则等待,等到解锁在查询数据。

数据库与缓存一致性

描述:场景一:当更新数据时,如更新某商品的库存,当前商品的库存是100,现在要更新为99,先更新数据库更改成99,然后删除缓存,发现删除缓存失败了,这意味着数据库存的是99,而缓存是100,这导致数据库和缓存不一致。
解决方案:

  • 1) 先删缓存,删缓存成功,再删数据库数据。缓存删除失败,则不删数据库。

描述:场景二:一个数据的修改还未提交到数据库,但是缓存数据已经被删除了。这个时候,如果有一个查询过来,则旧数据又被加入到缓存了。在这个缓存过期之前,请求的都是旧数据
解决方案: 网上给出的解决方案:::遇到这种情况,可以用队列的去解决这个问,创建几个队列,如20个,根据商品的ID去做hash值,然后对队列个数取摸,当有数据更新请求时,先把它丢到队列里去,当更新完后在从队列里去除,如果在更新的过程中,遇到以上场景,先去缓存里看下有没有数据,如果没有,可以先去队列里看是否有相同商品ID在做更新,如果有也把查询的请求发送到队列里去,然后同步等待缓存更新完成。
这里有一个优化点,如果发现队列里有一个查询请求了,那么就不要放新的查询操作进去了,用一个while(true)循环去查询缓存,循环个200MS左右,如果缓存里还没有则直接取数据库的旧数据,一般情况下是可以取到的。

猜你喜欢

转载自blog.51cto.com/12332955/2415978