高并发系统设计学习笔记(十三) 缓存穿透了怎么办

目录

一、问题描述

二、什么是缓存穿透

三、缓存穿透的解决方案

1.场景

2.回种空值

3.使用布隆过滤器

四、课程小结


一、问题描述

低缓存命中率的系统中,大量查询商品信息的请求会穿透缓存到数据库,因为数据库对于并发的承受能力是比较脆弱的。一旦数据库承受不了用户大量刷新商品页面、定向搜索衣服信息,查询就会变慢,大量的请求也会阻塞在数据库查询上,造成应用服务器的连接和线程资源被占满,最终导致你的电商系统崩溃

一般来说,我们的核心缓存的命中率要保持在99%以上,非核心缓存的命中率也要尽量保证在90%,如果低于这个标准你可能就需要优化缓存的使用方式了。

既然缓存的穿透会带来如此大的影响,那么我们该如何减少它的发生呢?本节课我就带你全面探知面对缓存穿透时,我们到底有哪些应对措施。不过在此之前你需要了解“到底什么是缓存穿透”,只有这样才能更好地考虑如何设计方案解决它。


二、什么是缓存穿透

缓存穿透其实是指从缓存中没有查到数据,而不得不从后端系统(比如数据库)中查询的情况

少量的缓存穿透不可避免,对系统也是没有损害的

  • 一方面,互联网系统通常会面临极大数据量的考验,而缓存系统在容量上是有限的,不可能存储系统所有的数据,那么在查询未缓存数据的时候就会发生缓存穿透。
  • 另一方面,互联网系统的数据访问模型一般会遵从“80/20原则”。“80/20原则”又称为帕累托法则,是意大利经济学家帕累托提出的一个经济学的理论。简单来说,它是指在一组事物中,最重要的部分通常只占20%,而其他的80%并没有那么重要。把它应用到数据访问的领域,就是我们会经常访问20%的热点数据,而另外的80%的数据则不会被经常访问。比如你买了很多衣服,很多书,但是其实经常穿的、经常看的可能也就是其中很小的一部分。

 大量的穿透请求超过了后端系统的承受范围造成了后端系统的崩溃。如果把少量的请求比作毛毛细雨,那么一旦变成倾盆大雨,引发洪水,冲倒房屋,肯定就不行了


三、缓存穿透的解决方案

1.场景

在你的电商系统的用户表中,我们需要

在你的电商系统的用户表中,我们需要通过用户ID查询用户的信息缓存的读写策略采用Cache Aside策略

那么如果要读取一个用户表中未注册的用户,会发生什么情况呢?按照这个策略,我们会先读缓存再穿透读数据库。由于用户并不存在,所以缓存和数据库中都没有查询到数据,因此也就不会向缓存中回种数据(也就是向缓存中设置值的意思),这样当再次请求这个用户数据的时候还是会再次穿透到数据库。在这种场景下缓存并不能有效地阻挡请求穿透到数据库上,它的作用就微乎其微了。

那如何解决缓存穿透呢?一般来说我们会有两种解决方案:回种空值以及使用布隆过滤器

2.回种空值

你会发现最大的问题在于数据库中并不存在用户的数据,这就造成无论查询多少次数据库中永远都不会存在这个用户的数据,穿透永远都会发生。

当我们从数据库中查询到空值或者发生异常时,我们可以向缓存中回种一个空值。但是因为空值并不是准确的业务数据,并且会占用缓存的空间,所以我们会给这个空值加一个比较短的过期时间,让空值在短时间之内能够快速过期淘汰

回种空值虽然能够阻挡大量穿透的请求,但如果有大量获取未注册用户信息的请求,缓存内就会有有大量的空值缓存,也就会浪费缓存的存储空间,如果缓存空间被占满了,还会剔除掉一些已经被缓存的用户信息反而会造成缓存命中率的下降。

3.使用布隆过滤器

我们把集合中的每一个值按照提供的Hash算法算出对应的Hash值,然后将Hash值对数组长度取模后得到需要计入数组的索引值,并且将数组这个位置的值从0改成1。在判断一个元素是否存在于这个集合中时,你只需要将这个元素按照相同的算法计算出索引值,如果这个位置的值为1就认为这个元素在集合中,否则则认为不在集合中。

A、B、C等元素组成了一个集合,元素D计算出的Hash值所对应的的数组中值是1,所以可以认为D也在集合中。而F在数组中的值是0,所以F不在数组中。 

那么我们如何使用布隆过滤器来解决缓存穿透的问题呢?

 我们初始化一个很大的数组,比方说长度为20亿的数组,接下来我们选择一个Hash算法,然后我们将目前现有的所有用户的ID计算出Hash值并且映射到这个大数组,映射位置的值设置为1其它值设置为0

新注册的用户除了需要写入到数据库中之外,它也需要依照同样的算法更新布隆过滤器的数组中相应位置的值。那么当我们需要查询某一个用户的信息时,先查询这个ID在布隆过滤器中是否存在,如果不存在就直接返回空值,而不需要继续查询数据库和缓存,这样就可以极大地减少异常查询带来的缓存穿透

 布隆过滤器拥有极高的性能,无论是写入操作还是读取操作时间复杂度都是O(1)是常量值。在空间上,相对于其他数据结构它也有很大的优势

有两个缺陷

1.它在判断元素是否在集合中时是有一定错误几率的,比如它会把不是集合中的元素判断为处在集合中

2.不支持删除元素

使用建议

1.选择多个Hash函数计算多个Hash值,这样可以减少误判的几率;

2.布隆过滤器会消耗一定的内存空间,所以在使用时需要评估你的业务场景下需要多大的内存,存储的成本是否可以接受


四、课程小结

  • 回种空值是一种最常见的解决思路,实现起来也最简单,如果评估空值缓存占据的缓存空间可以接受,那么可以优先使用这种方案;
  • 布隆过滤器会引入一个新的组件,也会引入一些开发上的复杂度和运维上的成本。所以只有在存在海量查询数据库中,不存在数据的请求时才会使用,在使用时也要关注布隆过滤器对内存空间的消耗;
  • 对于极热点缓存数据穿透造成的“狗桩效应”,可以通过设置分布式锁或者后台线程定时加载的方式来解决

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值