如何判断一个元素是否存在于一个亿级数据集中?

布隆过滤器的概念
布隆过滤器(Bloom Filter)于 1970 年由布隆提出的,是专门 用于检索一个元素是否存在于一个集合中的算法。

你可能会想,判断一个元素是否在集合中,这不就是集合自带的功能吗?

元素数量少的时候的确没问题,但如果有海量元素时就麻烦了,例如千万,甚至上亿个元素,而且每个元素的大小不一,有可能很大,这时集合的空间效率和查询效率都会堪忧。

而布隆过滤器就可以巧妙的解决这个问题,它包括了一个很长的二进制向量和一系列的hash函数,它不会实际存储元素内容,只是在二进制向量中标识这个元素是否存在,而 hash 函数就是用来定位元素的。

  1. 使用场景
    布隆过滤器的核心作用是 判断元素是否存在 ,在如今海量数据场景中可以起到非常大的作用。

例如:

2.1 防止数据库穿库
Bigtable、HBase 和 Cassandra 等大数据存储系统也会使用布隆过滤器。

查询操作是磁盘I/O,代价高昂,如果大量的查询不存在的数据,就会严重影响数据库性能。

使用布隆过滤器可以提前判断不存在的数据,避免不必要的磁盘操作。

2.2 防止缓存穿透
查询时一般会先判断是否在缓存中,如果没有,就读DB,并放入缓存。

这是正常流程,没有问题。

但如果有恶意请求,一直查询不存在的数据,例如查询用户abc的详细信息,而abc根本不存在。

按照正常流程的话,就肯定会去读DB,那数据库的压力就大了。

这时就可以使用布隆过滤器,例如请求用户abc的时候,先判断此用户是否存在,不存在就直接返回了,避免了数据库查询。

2.3 爬虫URL去重
避免爬取相同URL地址。

反垃圾邮件
从数十亿垃圾邮件列表中判断某邮箱是否为垃圾邮箱。

  1. 实现原理
    我们通过一个例子来理解其原理。

假设一个二进制数组,长度为8,初始值都为0(0表示不存在)。

现添加元素 张三 ,先通过hash函数定位其在二进制数组的位置,然后将此位置的值设为 1 :

hash1(张三) % 8 = 4

现在需要判断 李四 是否存在,用同样的方法计算出其位置,然后取此位置的值


值为 0 ,说明 李四 不存在。

这就是基本原理。

我们都知道哈希冲突是普遍存在的,所以通过一个hash函数定位元素是不可靠的。

例如张三、王五的hash定位都是4:

hash1(张三) % 8 = 4

hash1(王五) % 8 = 4

张三 是已经存在的元素, 王五 不存在,但因为 [4] 的值是 1 ,所以对 王五 的判断结果是 存在 ,这就误判了。

为了解决哈希冲突的问题,通常会使用多个hash函数对元素进行定位,例如:

同一个元素,经过多个不同的hash算法,计算出来的结果相同的概率就非常低了。

计算出来的位置的值如果包含 0 ,那么可以肯定元素一定不存在

相反,如果都是1,却不能肯定元素一定存在,因为可能有哈希冲突

Redis 实现布隆过滤器
Redis 4.0 推出了 module 模式,可以开发扩展模块, RedisBloom 就是布隆过滤器的扩展模块。

实践
启动带有 RedisBloom 的 Redis 环境:

docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest

进入容器中的 redis 客户端:

# 进入容器

docker exec -it redis-redisbloom bash

# 登录redis客户端

redis-cli

添加元素:

127.0.0.1:6379> BF.ADD newFilter foo

(integer) 1

检测元素是否存在:

127.0.0.1:6379> BF.EXISTS newFilter foo

(integer) 1

127.0.0.1:6379> BF.EXISTS newFilter foo2

(integer) 0

原文地址:https://blog.51cto.com/14528283/2453674

时间: 2024-08-05 12:45:07

如何判断一个元素是否存在于一个亿级数据集中?的相关文章

判断一个元素是否是另一个元素的子元素或者父元素

判断一个元素是否是另一个元素的子元素或者父元素:在实际应用中有时候会判断某个元素是另一个元素的子元素或者父元素,下面就通过代码实例介绍一下. //判断:当前元素是否是被筛选元素的子元素 jQuery.fn.isChildOf=function(b){ return (this.parents(b).length>0); }; //判断:当前元素是否是被筛选元素的子元素或者本身 jQuery.fn.isChildAndSelfOf=function(b){ return (this.closest

Python List pop()方法-用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值

描述 pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值. 语法 pop()方法语法: list.pop(obj=list[-1]) 参数 obj -- 可选参数,要移除列表元素的对象. 返回值 该方法返回从列表中移除的元素对象. 实例 以下实例展示了 pop()函数的使用方法: #!/usr/bin/python aList = [123, 'xyz', 'zara', 'abc']; print "A List : ", aList.pop(); pr

selenium webdriver学习(十)------------如何把一个元素拖放到另一个元素里面(转)

selenium webdriver学习(十)------------如何把一个元素拖放到另一个元素里面 博客分类: Selenium-webdriver 元素拖放drag and drop Q群里有时候会有人问,selenium  webdriver怎么实现把一个元素拖放到另一个元素里面.这一节总一下元素的拖放. 下面这个页面是一个演示拖放元素的页面,你可以把左右页面中的条目拖放到右边的div框中. http://koyoz.com/demo/html/drag-drop/drag-drop.

javascript判断一个元素是另外一个元素的子元素

javascript判断一个元素是另外一个元素的子元素用途有很多,最常用的就是当点击页面的空白处去执行某些操作,比如弹出层等. function isParent (obj,parentObj){ while (obj != undefined && obj != null && obj.tagName.toUpperCase() != ‘BODY’){ if (obj == parentObj){ return true; } obj = obj.parentNode;

js如何判断一个元素是否获得焦点

js如何判断一个元素是否获得焦点:可能在实际应用中需求不多,也或许使用以下方式判断过于直白,不过原理总是那么回事,下面就是一个简单的判断元素是否获得焦点的例子,代码如下: $("#theid").click(function(){ var act = document.activeElement.id; if(act=="theid" ){ alert("获取焦点了"); } else{ alert("没有获取焦点"); }

jQuery如何判断某一个元素是否存在

jQuery如何判断某一个元素是否存在:判断一个元素是否存在的方法有多重,下面介绍一种比较简单的,看下面的代码: $(".mytest").length 通过判断length属性值就可以知道是否存在,如果大于0就是存在,否则就是不存在. 原文地址是:http://www.softwhy.com/forum.php?mod=viewthread&tid=9654 更多内容可以参阅:http://www.softwhy.com/jquery/

python中如何不区分大小写的判断一个元素是否在一个列表中

python中判断某一个元素是否在一个列表中,可以使用关键字in 和 not in. 示例如下: 如果需要输出相应的信息,可以搭配使用if语句,这里不赘述. ------------------------------------------------------------------------------------------分割线------------------------------------------------------------------------------

用jQuery判断一个元素的各种状态

用jQuery判断一个元素是否显示 用jQuery判断一个元素是否显示:$(element).is(":visible"); 类似的,判断一个元素是不是第一个子元素:$(element).is(":first-child") 判断一个checkbox元素是否选中:$(element).is(":checked") 判断一个元素是否存在:$(element).length 判断一个字符串中是否包含其他字符串:str.indexOf("ab

javascript selenium判断一个元素存在的方法(CukeTest环境)

1.在[features]-[step_definitions]目录下创建自己的一个js文件,内容如下 var { Given, When, Then } = require('cucumber') const { driver } = require('../support/web_driver'); const {By,until,Key} = require('selenium-webdriver'); async function isExist(ele) { var bool=null