解决微服务缓存常见问题——缓存击穿

“缓存”和“击穿”

什么是缓存?

缓存就是数据交换的缓冲区。
我们通常的理解缓存的主要作用是提高查询效率。其实它还有着另一个非常重要的作用,就是上面提到的“缓冲”也就是对下层资源的保护作用。

如何理解击穿

很简单,我们上面提到的缓存的另外一个主要作用是“缓冲”对下层资源的防护,那么“击穿“就是让你的缓冲失效,从而对被保护的资源进行”冲击“。
回到我们所开发的系统中,我们常常用缓存中间件如redis等,作为我们的缓存数据存储。当请求到达服务端时,我们优先查询缓存,缓存如果不存在,再查询数据库,如果查询到将数据写回缓存,使得下一次同样的请求能够命中缓存。如下图所示:
解决微服务缓存常见问题——缓存击穿
当大多数正常请求到达服务,大多会命中缓存数据库,也就是左半边红色部分(表示资源忙碌)。当一些攻击性请求,特意查询缓存中不存在的数据时,这时候按照我们上述处理逻辑,会直接透过缓存,到达数据库,进而对数据库进行流量冲击,体现为图中右半部分。

一种有效的解决缓存击穿利器——布隆过滤器

之上部分,我们提到了特意查询缓存数据库中不存在的数据会对数据库造成冲击,而数据库相对缓存,查询效率低很多,当大批量请求到达数据库,数据库因性能问题导致不再能及时响应请求,甚至出现宕机。那么我们如何进行防护?
我们换种思路出发,如果能够判断出,哪些请求一定是系统中不存在的数据时,是不是就可以将请求进行拦截,不让请求到达数据层?答案:YES
在这里,我们介绍一种有效的思路——布隆过滤器

布隆过滤器概念

什么是布隆过滤器?
本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),
特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”。

布隆过滤器数据结构

布隆过滤器是一个bit向量或者说bit数组,如下图:
解决微服务缓存常见问题——缓存击穿

布隆过滤器原理分析

如果我们要映射一个值到布隆过滤器中,我们需要使用多个不同的哈希函数生成多个哈希值,并对每个生成的哈希值指向bit位置1,例如针对值”baidu“和三个不同的哈希函数分别生成了哈希值1、4、7,如下图所示:解决微服务缓存常见问题——缓存击穿
OK,我们再存一个值”tencent“,如果哈希函数返回3、4、8的话,图则继续变为:
解决微服务缓存常见问题——缓存击穿

值得注意的是,4 这个 bit 位由于两个值的哈希函数都返回了这个 bit 位,因此它被覆盖了。现在我们如果想查询 “dianping” 这个值是否存在,哈希函数返回了 1、5、8三个值,结果我们发现 5 这个 bit 位上的值为 0,说明没有任何一个值映射到这个 bit 位上,因此我们可以很确定地说 “dianping” 这个值不存在。而当我们需要查询 “baidu” 这个值是否存在的话,那么哈希函数必然会返回 1、4、7,然后我们检查发现这三个 bit 位上的值均为 1,那么我们可以说 “baidu” 存在了么?答案是不可以,只能是 “baidu” 这个值可能存在。

云顶云(yundingyun.com)是国内首批专注于云计算与大数据服务的提供商,致力于“让云计算更简单”。做为阿里云五星授权服务中心,云顶云致力于为企业和*提供方案咨询、架构设计、部署实施、系统定制、运维托管、技术培训等全方位“4S”级公有云、私有云定制化服务。

上一篇:搭建基于OSS的图片分享网站


下一篇:SLB+Tomcat时request.RemoteAddr无法获取正确的客户端IP的问题解决方案