布隆过滤器误判怎么办为什么会_最牛一篇布隆过滤器详解,布隆过滤器使用原理...

前言

我们之前讲了Redis的缓存雪崩、穿透、击穿。在文章里我们说了解决缓存穿透的办法之一,就是布隆过滤器,但是上次并没有讲如何使用布隆过滤器。

作为暖男的老哥,给你们补上,请叫我IT老暖男。

什么是布隆过滤器

布隆过滤器(Bloom Filter),是1970年,由一个叫布隆的小伙子提出的,距今已经五十年了,和老哥一样老。

它实际上是一个很长的二进制向量和一系列随机映射函数,二进制大家应该都清楚,存储的数据不是0就是1,默认是0。

主要用于判断一个元素是否在一个集合中,0代表不存在某个数据,1代表存在某个数据。

懂了吗?作为暖男的老哥在给你们画张图来帮助理解:

布隆过滤器用途解决Redis缓存穿透(今天重点讲解)

在爬虫时,对爬虫网址进行过滤,已经存在布隆中的网址,不在爬取。

垃圾邮件过滤,对每一个发送邮件的地址进行判断是否在布隆的黑名单中,如果在就判断为垃圾邮件。

以上只是简单的用途举例,大家可以举一反三,灵活运用在工作中。

布隆过滤器原理

存入过程

布隆过滤器上面说了,就是一个二进制数据的集合。当一个数据加入这个集合时,经历如下洗礼(这里有缺点,下面会讲):通过K个哈希函数计算该数据,返回K个计算出的hash值

这些K个hash值映射到对应的K个二进制的数组下标

将K个下标对应的二进制数据改成1。

例如,第一个哈希函数返回x,第二个第三个哈希函数返回y与z,那么: X、Y、Z对应的二进制改成1。

如图所示:

查询过程

布隆过滤器主要作用就是查询一个数据,在不在这个二进制的集合中,查询过程如下:通过K个哈希函数计算该数据,对应计算出的K个hash值

通过hash值找到对应的二进制的数组下标

判断:如果存在一处位置的二进制数据是0,那么该数据不存在。如果都是1,该数据存在集合中。(这里有缺点,下面会讲)

删除过程

一般不能删除布隆过滤器里的数据,这是一个缺点之一,我们下面会分析。

布隆过滤器的优缺点

优点由于存储的是二进制数据,所以占用的空间很小

它的插入和查询速度是非常快的,时间复杂度是O(K),可以联想一下HashMap的过程

保密性很好,因为本身不存储任何原始数据,只有二进制数据

缺点

这就要回到我们上面所说的那些缺点了。

添加数据是通过计算数据的hash值,那么很有可能存在这种情况:两个不同的数据计算得到相同的hash值。

例如图中的“你好”和“hello”,假如最终算出hash值相同,那么他们会将同一个下标的二进制数据改为1。

这个时候,你就不知道下标为2的二进制,到底是代表“你好”还是“hello”。

由此得出如下缺点:

一、存在误判

假如上面的图没有存"hello",只存了"你好",那么用"hello"来查询的时候,会判断"hello"存在集合中。

因为“你好”和“hello”的hash值是相同的,通过相同的hash值,找到的二进制数据也是一样的,都是1。

二、删除困难

到这里我不说大家应该也明白为什么吧,作为你们的暖男老哥,还是讲一下吧。

还是用上面的举例,因为“你好”和“hello”的hash值相同,对应的数组下标也是一样的。

这时候老哥想去删除“你好”,将下标为2里的二进制数据,由1改成了0。

那么我们是不是连“hello”都一起删了呀。(0代表有这个数据,1代表没有这个数据)

到这里是不是对布隆过滤器已经明白了,都说了我是暖男。

实现布隆过滤器

有很多种实现方式,其中一种就是Guava提供的实现方式。

一、引入Guava pom配置

com.google.guava

guava

29.0-jre

二、代码实现

这里我们顺便测一下它的误判率。

import com.google.common.hash.BloomFilter;

import com.google.common.hash.Funnels;

public class BloomFilterCase {

/**

* 预计要插入多少数据

*/

private static int size = 1000000;

/**

* 期望的误判率

*/

private static double fpp = 0.01;

/**

* 布隆过滤器

*/

private static BloomFilter bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, fpp);

public static void main(String[] args) {

// 插入10万样本数据

for (int i = 0; i < size; i++) {

bloomFilter.put(i);

}

// 用另外十万测试数据,测试误判率

int count = 0;

for (int i = size; i < size + 100000; i++) {

if (bloomFilter.mightContain(i)) {

count++;

System.out.println(i + "误判了");

}

}

System.out.println("总共的误判数:" + count);

}

}

运行结果:

10万数据里有947个误判,约等于0.01%,也就是我们代码里设置的误判率:fpp = 0.01。

深入分析代码

核心BloomFilter.create方法

@VisibleForTesting

static BloomFilter create(

Funnel super T> funnel, long expectedInsertions, double fpp, Strategy strategy) {

。。。。

}

这里有四个参数:funnel:数据类型(一般是调用Funnels工具类中的)

expectedInsertions:期望插入的值的个数

fpp:误判率(默认值为0.03)

strategy:哈希算法

我们重点讲一下fpp参数

fpp误判率

情景一:fpp = 0.01误判个数:947占内存大小:9585058位数

情景二:fpp = 0.03(默认参数)误判个数:3033占内存大小:7298440位数

情景总结误判率可以通过fpp参数进行调节

fpp越小,需要的内存空间就越大:0.01需要900多万位数,0.03需要700多万位数。

fpp越小,集合添加数据时,就需要更多的hash函数运算更多的hash值,去存储到对应的数组下标里。(忘了去看上面的布隆过滤存入数据的过程)

上面的numBits,表示存一百万个int类型数字,需要的位数为7298440,700多万位。理论上存一百万个数,一个int是4字节32位,需要481000000=3200万位。如果使用HashMap去存,按HashMap50%的存储效率,需要6400万位。可以看出BloomFilter的存储空间很小,只有HashMap的1/10左右

上面的numHashFunctions表示需要几个hash函数运算,去映射不同的下标存这些数字是否存在(0 or 1)。

解决Redis缓存雪崩

上面使用Guava实现的布隆过滤器是把数据放在了本地内存中。分布式的场景中就不合适了,无法共享内存。

我们还可以用Redis来实现布隆过滤器,这里使用Redis封装好的客户端工具Redisson。

其底层是使用数据结构bitMap,大家就把它理解成上面说的二进制结构,由于篇幅原因,bitmap不在这篇文章里讲,我们之后写一篇文章介绍。

代码实现

pom配置:

org.redisson

redisson-spring-boot-starter

3.13.4

java代码:

public class RedissonBloomFilter {

public static void main(String[] args) {

Config config = new Config();

config.useSingleServer().setAddress("redis://127.0.0.1:6379");

config.useSingleServer().setPassword("1234");

//构造Redisson

RedissonClient redisson = Redisson.create(config);

RBloomFilter bloomFilter = redisson.getBloomFilter("phoneList");

//初始化布隆过滤器:预计元素为100000000L,误差率为3%

bloomFilter.tryInit(100000000L,0.03);

//将号码10086插入到布隆过滤器中

bloomFilter.add("10086");

//判断下面号码是否在布隆过滤器中

//输出false

System.out.println(bloomFilter.contains("123456"));

//输出true

System.out.println(bloomFilter.contains("10086"));

}

}

由于Guava那个版本,我们已经很详细的讲了布隆过滤器的那些参数,这里就不重复赘述了。

老哥在这里给大家准备了2020年最新Java面试题,涵盖Java各个技术领域。共80多个PDF,BAT面试必备

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/489331.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

thinkPHP-空操作

空操作 当访问的方法不存在时&#xff0c;可以定义一个empty方法来避免空操作 function _empty(){echo "网页不存在&#xff0c;请检查地址信息";} 这样当访问不存在的方法时就会显示以上信息 当访问的控制器不存在时&#xff0c;可以定义一个空操作器 <?php nam…

python3 面向对象_Python3 面向对象

Python和C都是一门面向对象的语言&#xff0c; 面向对象技术简介 类(Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。比如 f file()##创建了一个类(file())的对象f 类变量&#xff1a;类变量在整个实例的对象…

口腔ct重建服务器原理,牙科CT是什么?牙科CT的原理及优势介绍

原标题&#xff1a;牙科CT是什么&#xff1f;牙科CT的原理及优势介绍牙科CT是什么&#xff1f;牙科CT&#xff0c;又称口腔CT&#xff0c;是一种新型牙科类仪器&#xff0c;它可以从三维角度对口腔部组织情况进行扫描检查。牙科CT在业界被誉为神奇的“慧眼”&#xff0c;它犹如…

机器学习奠基人Michael Jordan:下代技术是融合经济学,解读2项重要进展

来源&#xff1a; 北京智源人工智能研究院2019年11月1日北京智源大会全体大会及闭幕式上&#xff0c;被誉为“机器学习之父”的加州大学伯克利教授、智源研究院学术顾问委员会委员 Michael I.Jordan 做了题为《决策与情境&#xff1a;基于梯度的博弈均衡求解方法》&#xff08;…

matlab 带有下标的赋值维度不匹配_远见另类资产管理体系下的核心系统搭建

另类资产管理体系下的信息化建设&#xff0c;或许是小众领域中的更小众话题&#xff0c;但仍值得讨论。很多基金公司、投资公司或资产管理公司都搭建了各种大大小小的应用系统&#xff0c;如OA系统、财务系统、CRM系统等&#xff0c;但对于上系统的价值&#xff0c;不仅很难量化…

cfree运行程序错误的原因_Python入门教程 | 第 8 章 错误、调试和测试

第八章 错误、调试和测试在程序运行过程中&#xff0c;总会遇到各种各样的错误。有的错误是程序编写有问题造成的&#xff0c;比如本来应该输出整数结果输出了字符串&#xff0c;这种错误我们通常称之为bug&#xff0c;bug是必须修复的。有的错误是用户输入造成的&#xff0c;比…

python更新后yum问题

python更新后yum问题 How to switch between Python versions on Fedora Linux Currently, the default python version on Fedora Linux is Python 2. Later Fedora Linux release 22 will ship with the Python 3 as a default version. In this config you will learn how t…

我的世界服务器物品id错误,我的世界错误代码,怎么弄

我的世界错误代码&#xff0c;怎么弄0xu1125yuan2017.07.24浏览323次分享举报1.Minecraft:[16:05:37][Clientthread/FATAL][NotEnoughItemsFingerprintVerification]:ThefingerprintformodNotEnoughItemsisinvalid!Expected:f1850c39b2516232a2108a7bd84d1cb5df9... 1.Minecraf…

友友球捕获率_神奇宝贝球内部秘密公开!大师球原来是这样达到100%捕获率的...

要想获得神奇宝贝&#xff0c;首先就要用精灵球&#xff0c;精灵球的作用是捕捉或者携带宝可梦&#xff0c;不同种类的精灵球拥有不同的特殊效果。一名训练家最多只能携带6枚装有宝可梦的精灵球&#xff0c;空的精灵球则没有携带数量的限制。目前为止&#xff0c;已经有27种不同…

今日头条CEO朱文佳:新一代搜索引擎已经来了

来源&#xff1a;今日头条11月27日&#xff0c;今日头条CEO朱文佳在36kr wise大会上谈及头条搜索。在他看来&#xff0c;要做好搜索&#xff0c;有三件事最重要。首先是技术&#xff0c;技术决定搜索的体验&#xff1b;其次是内容&#xff0c;内容是搜索的根本&#xff1b;最后…

javascript事件监听与事件委托

事件监听与事件委托 在js中&#xff0c;常用到element.addEventListener()来进行事件的监听。但是当页面中存在大量需要绑定事件的元素时&#xff0c;这种方式可能会带来性能影响。此时&#xff0c;我们可以用事件委托的方式来进行事件的监听。 每个事件都经历三个阶段 捕获到达…

串口打印怎么使用】_爱普生打印机怎么使用 爱普生打印机使用方法【详解】...

市面上的打印机品牌有很多&#xff0c;其中就有爱普生打印机&#xff0c;这个品牌的打印机是在上个世纪的四十年代成立的&#xff0c;并且爱普生这款打印机逐渐深入我们的生活&#xff0c;一般我们很多都会使用爱普生打印机来打印资料或者是下载各种工作材料&#xff0c;那么你…

中科院大学计算机研究生考试大纲,中国科学院大学《计算机原理》2019年硕士研究生入学考试大纲...

(二)计算机组成原理 (50分)1、计算机系统概论(1)计算机的分类。(2)计算机的硬件。(3)计算机的软件。(4)计算机系统的层次结构。2、 运算方法和运算器(1)数据与文字的表示方法。(2)定点加法、减法运算。(3)定点乘法运算。(4)定点除法运算。(5)定点运算器的组成。(6)浮点运算方法…

linux 测试cpu计算圆周率_Linux下测试CPU性能

一、安装stress服务2、解压tar xvf stress_1.0.1.orig.tar.gz3、进入解压目录执行./configure4、make5、make check6、make install7、make clean二、安装sysstat服务2、解压tar xvf sysstat-11.5.6.tar.gz3、进入解压目录执行./configure4、make & make install三、测试C…

日益谨慎的谷歌AI,会在自我限制中越走越慢吗?

来源&#xff1a;wired为了防止技术被滥用&#xff0c;谷歌对新推出的人脸识别服务进行了限制&#xff0c;但这种限制有时候反而会让竞争对手抢得市场先机。谷歌之所以成为今天的谷歌&#xff0c;是因为它不断创造先进的新技术&#xff0c;并将这些技术向所有人开放。大型企业和…

用jsp实现右导航窗格_手机导航如何投放到汽车中控屏?建议用这2种办法,轻松实现同屏...

对于我们许多的司机来说&#xff0c;虽然车上有车载导航&#xff0c;但是出于个人习惯&#xff0c;我们很多人还是习惯用手机导航&#xff0c;由于手机导航它的定位较为精准&#xff0c;而且使用起来比较方便&#xff0c;所以说更受司机朋友的青睐&#xff0c;但是有一个毛病就…

MFC编程入门之十五(对话框:一般属性页对话框的创建及显示)

属性页对话框包括向导对话框和一般属性页对话框两类&#xff0c;上一节讲了如何创建并显示向导对话框&#xff0c;本节将继续介绍一般属性页对话框的创建和显示。 实际上&#xff0c;一般属性页对话框的创建和显示过程和向导对话框是很类似的。将上一节中的向导对话框进行少量修…

javascript 等待指定时间_javascript的单线程和任务队列

一、JavaScript为什么设计为单线程&#xff1f;JavaScript语言的一大特点就是单线程&#xff0c;换言之就是同一个时间只能做一件事。其他任务都必须在后面排队等待。for(var i 0; i < 5; i) {console.log(i); } console.log(end);上面的代码&#xff0c;只有for循环执行完…

2019年云计算行业深度报告

来源&#xff1a;西部证券 导语 根据 Gartner 数据 2018 年全球公有云市场规模达到 1392 亿美元&#xff0c;2015 年至 2018 年复合增长 28.24%&#xff0c;预计 2021 年规模将达到 2461 亿美元。 一、云计算蓬勃发展&#xff0c;驱动数据中心基础设施采购 1.1 云计算蓬勃发展&…

dataframe 一列的不同值_pandas | 详解DataFrame中的apply与applymap方法

点击上方蓝字&#xff0c;关注并星标&#xff0c;和我一起学技术。今天是pandas数据处理专题的第5篇文章&#xff0c;我们来聊聊pandas的一些高级运算。在上一篇文章当中&#xff0c;我们介绍了panads的一些计算方法&#xff0c;比如两个dataframe的四则运算&#xff0c;以及da…