Redis的缓存一致性/缓存溢出/缓存雪崩/缓存穿透/缓存击穿

尝试用一个例子来描述高并发系统下的缓存设计,一边举例子一边描述和解决以下问题。

问题:

假设我们有5000万条商品信息存储在数据库中,现在这些信息要展示给用户看,我们需要做什么?

答案1:直连数据库

答案2:加缓存(例如Redis)

缓存一致性问题

当修改一条商品信息,MySQL和Redis缓存都需要修改,两者之间会有先后顺序,可能导致数据不一致。

1、先更新缓存还是先更新数据库?

2、更新缓存的时候,是更新(update)缓存,还是删除(delete)缓存?

3.怎么更新缓存保证一致性?

数据库事务方案:

缓存延迟双删方案

缓存延迟双删方案消息队列改进版

缓存延迟双删方案binlog改进版

看到这里,我们知道为了提高系统在高访问量的并发性,解决数据库瓶颈,引入了缓存(Redis)。又为了解决缓存的一致性,引入了各种复杂双删策略,引入了消息队列(MQ),binlog服务(cannal), 为了能让程序更加快速,满足高并发,我们搞了这么多事。

别急,这还没完。继续往下想,还有很多事情。

缓存溢出

还是刚才的问题继续想一下,这5000万条数据都放到缓存里面吗?

缓存溢出的解决方法

缓存雪崩

继续刚才的问题,现在已经给商品的key设置了过期时间(假定是24小时),假如有一个供应商在昨天的17:00 批量修改了100万条商品信息,那么这100万条商品信息在redis中都将会在今天的17:00失效。此时就会引起缓存雪崩。

缓存雪崩的解决方法

针对缓存集中过期:

针对Redis集群故障:

缓存穿透

现在有个id为9527的前热门商品下架了,数据库里删除了,现在有大量的访问一直要访问9527这个商品,此时缓存中没有,会透到数据库中

缓存穿透的解决方法

缓存穿透Plus(黑客/爬虫)

假定有黑客/或爬虫程序一直在遍历不存在的id(这个量可能会大的吓人)

缓存穿透Plus的解决方法

缓存击穿

现在不是被人攻击了,就是一个很热门的商品(每秒种几百万次点击)被修改了,此时这个商品的缓存失效了。高并发场景同一时刻有大量的访问,发现没有缓存

缓存击穿的解决方法

小结

说了这么多,都是在说高并发情况下需要考虑到的问题及解决方法。为了应对高并发场景,我们肉眼可见的提高了代码的复杂度和设计的复杂度。只有充分的了解和考虑到这些风险点并提前加以处理和规避,才能让一个系统在高并发的时候保持:稳定/健壮/不出错。如果你的系统没有高并发,可以不用这么折腾,因为过度设计也是一种浪费,该直连数据库就直连数据库吧。或者简单的套个redis做缓存也足够了。

>> Home

51ak

2022/11/11

Categories: redis Tags: 原创 精品

《数据库工作笔记》公众号
扫描上面的二维码,关注我的《数据库工作笔记》公众号