高可用服务设计之如何应对缓存穿透

高可用服务设计之如何应对缓存穿透

背景

用户中心是授权逻辑与用户信息相关逻辑构建的应用。分布式系统中,大多数业务都需要和用户中心打交道,为了保证用户中心服务的高可用,避免不了做缓存、导入搜索引擎从而降低数据库的压力。然而有些不经过用户中心授权的业务场景查询用户中心的数据,可能引发大量无效的查询,发生缓存穿透,直接对搜索引擎和数据库造成压力。如何解决用户中心缓存穿透的问题呢?接下来就着重说一下布隆过滤器是怎么“隔档”这些无效查询的

缓存穿透

缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到对应keyvalue,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请求就绕过缓存直接查数据库

布隆过滤器 基本概念

布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量(位图)和一系列随机映射函数(哈希函数)。

布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。

特点

空间效率高和查询效率高的概率型数据结构。

对于一个元素检测是否存在的调用,BloomFilter会告诉调用者两个结果之一:可能存在或者一定不存在。

一个很长的二进制向量 (位数组)

一系列随机函数哈希)。

有一定的误判率(哈希表是精确匹配)

原理

布隆过滤器(Bloom Filter)的核心实现是一个超大的位数组和几个哈希函数。假设位数组的长度为m,哈希函数的个数为k

高可用服务设计之如何应对缓存穿透

(1) 添加元素过程

将要添加的元素给k个哈希函数。

得到对应于位数组上的k个位置。

将这k个位置设为1。

(2) 查询元素过程

将要查询的元素给k个哈希函数。

得到对应于位数组上的k个位置。

如果k个位置有一个为0,则肯定不在集合中。

如果k个位置全部为1,则可能在集合中。

相关公式

很显然,根据布隆过滤器的原理和特性,bit数组大小和哈希函数的个数都会影响误判率。那么布隆过滤器是如何权衡bit数组大小和哈希函数个数的呢?

布隆过滤器bit数组大小为m,样本数量为n,失误率为p

高可用服务设计之如何应对缓存穿透

假设样本容量n=5000W,误判率是0.03,那么所需要的内存空间大小是m = -5000W * -3.057 / (0.7)^2 318,437,500 39.8MB

演示

(1)参考地址

https://www.jasondavies.com/bloomfilter

(2)可能存在

 

高可用服务设计之如何应对缓存穿透

 

 

 (3)一定不存在

高可用服务设计之如何应对缓存穿透

Guava Bloom Filter

Guava中,布隆过滤器的实现主要涉及到2个类, BloomFilterBloomFilterStrategies首先来看一下 BloomFilter的成员变量。需要注意的是不同Guava版本的 BloomFilter实现不同。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyswwf.html