08-BloomFilter解决Redis缓存穿透问题

目录

一 什么是 BloomFilter

二 BloomFilter 原理

2.1 布隆过滤器添加元素

2.2 布隆过滤器检索元素

2.3 举例说明 BloomFilter 原理 

三 BloomFilter 的缺点

四 BloomFilter 的实现

五  BloomFilter 解决缓存穿透问题

5.1 什么是缓存穿透

5.2 BloomFilter 解决缓存穿透问题


一 什么是 BloomFilter

       布隆过滤器实际上是一个很长的二进制向量和一系列随机映射函数。

       布隆过滤器用于检索一个元素是在集合中的状态可以得到下面两种情况:1 一定不在集合中;2 可能存在集合中。

二 BloomFilter 原理

       布隆过滤器(Bloom Filter)的核心实现是一个超大的位数组和几个哈希函数。

2.1 布隆过滤器添加元素

       1 将要添加的元素通过 K 个散列函数进行映射,得到一个位数组中的 K 个点;

       2 将位数组中的 K 个点的值置成1。

2.2 布隆过滤器检索元素

       1 将要查询的元素通过 K 个散列函数进行映射,得到一个位数组中的 K 个点;

       2 判断位数组中的 K 个点对应的值。

       3 如果 K 个点对应的值有一个为0,则一定不在集合中。

       4 如果 K 个点对应的值全部为1,则可能存在集合中。

2.3 举例说明 BloomFilter 原理 

       如下图所示“张三”经过四个 Hash 函数映射使得位数组中1,6,11,14四个点的值设置为1;

         “李四”经过四个 Hash 函数映射使得位数组中4,6,10,12四个点的值设置为1;

       1 如果说当我们要查询“王五”是否在集合中,假设返回2,3,4,5四个位置,由于四个位置中有值为0,所以我们肯定“王五”不在集合中。

       2 如果说我们要查询“张三”是否在集合中,返回1,6,11,14四个位置,四个位置的值都为1,则“张三”可能在集合中。

       3 到这里你可能会问“张三”明明就在集合中啊,为啥还叫可能在集合中?

       因为随着增加的值越来越多,被置为1的 bit 位也会越来越多,会出现 “赵六” 即使没有被放入集合中,哈希函数返回的四个 bit 位都被其他值置成了1 ,那么程序还是会判断 “赵六” 这个值可能在集合中。

三 BloomFilter 的缺点

   布隆过滤器之所以能做到在时间和空间上的效率比较高,是因为牺牲了判断的准确率、删除的便利性。

  • 存在误判,可能要查到的元素并没有在容器中,但是 Hash 之后得到的 K 个位置上值都是1。如果 bloomfilter 中存储的是黑名单,那么可以通过建立一个白名单来存储可能会误判的元素。

  • 删除困难。一个放入容器的元素映射到 bit 数组的k个位置上是1,删除的时候不能简单的直接置为0,可能会影响其他元素的判断。可以采用Counting Bloom Filter

四 BloomFilter 的实现

       请参考文章:https://juejin.im/post/5db69365518825645656c0de#heading-4

五  BloomFilter 解决缓存穿透问题

5.1 什么是缓存穿透

       缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,缓存穿透将导致不存在的数据每次请求都要到存储层去查询,存储层负载很大,甚至宕机。

5.2 BloomFilter 解决缓存穿透问题

       先把数据库的数据都加载到我们的 BloomFilter 中,业务 id 如果不存在 BloomFilter 直接异常返回,如下图所示:

猜你喜欢

转载自blog.csdn.net/jack1liu/article/details/107135903
今日推荐