布隆过滤器

布隆过滤器

十年热恋 提交于 2020-01-30 14:50:10
不同的数据结构有不同的适用场景和优缺点,你需要仔细权衡自己的需求之后妥善适用它们,布隆过滤器就是践行这句话的代表。 什么是布隆过滤器 本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”。 相比于传统的 List、Set、Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的。 实现原理 HashMap 的问题 讲述布隆过滤器的原理之前,我们先思考一下,通常你判断某个元素是否存在用的是什么?应该蛮多人回答 HashMap 吧,确实可以将值映射到 HashMap 的 Key,然后可以在 O(1) 的时间复杂度内返回结果,效率奇高。但是 HashMap 的实现也有缺点,例如存储容量占比高,考虑到负载因子的存在,通常空间是不能被用满的,而一旦你的值很多例如上亿的时候,那 HashMap 占据的内存大小就变得很可观了。 还比如说你的数据集存储在远程服务器上,本地服务接受输入,而数据集非常大不可能一次性读进内存构建 HashMap 的时候,也会存在问题。 布隆过滤器数据结构 布隆过滤器是一个 bit 向量或者说 bit 数组,长这样: image 如果我们要映射一个值到布隆过滤器中

自定义实现的布隆过滤器

半腔热情 提交于 2020-01-22 21:16:00
自定义实现的布隆过滤器 布隆过滤器是一种检索一个元素是否在一个集合中的算法,它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率。 它能准确判断一个元素不在集合中,大概率判断一个元素在集合中。 基本原理 布隆过滤器数据结构布隆过滤器是一个 bit 向量或者说 bit 数组,长这样: 如果我们要映射一个值到布隆过滤器中,我们需要使用多个不同的哈希函数生成多个哈希值,并对每个生成的哈希值指向的 bit 位置 1,例如针对值 “baidu” 和三个不同的哈希函数分别生成了哈希值 0、3、6,则上图转变为: Ok,我们现在再存一个值 “tencent”,如果哈希函数返回 2、3、7 的话,图继续变为: 值得注意的是,3 这个 bit 位由于两个值的哈希函数都返回了这个 bit 位,因此它被覆盖了。现在我们如果想查询 “dianping” 这个值是否存在,哈希函数返回了 0、4、7三个值,结果我们发现 4 这个 bit 位上的值为 0,说明没有任何一个值映射到这个 bit 位上,因此我们可以很确定地说 “dianping” 这个值不存在。而当我们需要查询 “baidu” 这个值是否存在的话,那么哈希函数必然会返回 1、4、7,然后我们检查发现这三个 bit 位上的值均为 1,那么我们可以说 “baidu” 存在了么?答案是不可以,只能是 “baidu” 这个值可能存在。

布隆过滤器

天涯浪子 提交于 2020-01-18 03:26:07
这玩意用来干嘛呢?我说个场景:我给你推送新闻,理论上来讲每条新闻只能推送一次,那么该如何确保每条新闻只对你推送一次呢? 布隆过滤器就是用来解决此类问题的,虽然稍微有那么点不精确,但人家在空间上能节省90%以上。Redis4.0之后才提供该功能。 其特点就是:当布隆过滤器说某个值存在时,这个值可能不存在;当它说不存在时,那就肯定不存在。 常用指令: bf.add:添加元素,只能一次添加一个元素 bf.exists:查询元素是否存在 bf.madd:指令一次添加多个 bf.mexists:指令一次查询多个元素 还提供了自定义参数的布隆过滤器,需要在add之前使用bf.reserve指令显式创建。如果重复创建则bf.reserve会报错。 bf.reserve有三个参数:key,error_rate和initial_size。 error_rate错误率,其数字越低,则需要的空间越大。 initial_size参数表示预计放入的元素数量,当实际数量超出这个数值时,误判率会上升。所以要提前设置一个较大的数值避免超出导致误判率升高。如果不使用 bf.reserve,默认的error_rate是 0.01,默认的initial_size是100。 注意事项: initial_size估值过大则会浪费存储空间,否则估值过小则会影响准确率,因此尽量在使用之前尽可能地精确估计好元素数量

HBase的RowKey与列族设计原则

♀尐吖头ヾ 提交于 2020-01-17 07:34:49
Roekey 设计原则: 1)Rowkey的长度原则: 是一个二进制码流,Rowkey 的长度被很多开发者建议说设计在10~100 个字节,不过建议是越短越好,不要超过16 个字节。 2)Rowkey散列原则:如果Rowkey 是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将Rowkey的高位作为散列字段,由程序循环生成,低位放时间字段,这样将提高数据均衡分布在每个Regionserver 实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息将产生所有新数据都在一个 RegionServer 上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别RegionServer,降低查询效率。 3)Rowkey唯一原则:必须在设计上保证其唯一性。 列族设计原则: (1)一般不建议设计多个列族。具体原因如下 假如HBase表的表设置两个列族,若已一个列族1000万行,另一个列族100行。当一个要求region分裂时候,会导致100行的列会同样分布到多个region中。这样就出现基数问题,会导致扫描列族A的性能低下。某个列族在flush的时候,它邻近的列族也会因关联效应出发flush,最终导致系统产生更多的I/O。 HBase本身的设计目标是支持稀疏表,而稀疏表通常会有很多列,但是每一行有值的列又比较少。在HBase中Column Family的数量通常很小

布隆过滤器

£可爱£侵袭症+ 提交于 2020-01-09 13:48:20
布隆过滤器 概念 布隆过滤器是概率型数据结构,由一个二进制向量和一系列随机映射函数组成。它可以用于检索一个元素是否在一个集合中。 实现过程 定义向量长度,并赋初值为0. 定义N个hash函数,并指定个数(1,N) 将需要存储的值经过n个hash计算得出的值作为key来修改向量的值(0=>1) 查询某个变量值是否不存在布隆过滤器里,只需要看它的hash值所对应的向量值是否为0,如果有一个为0,则一定不存在。如果全部为1,也不能证明该变量值一定在布隆过滤器里。 图例展示 初始化向量,并赋予初值为0 添加数据 检查数据 获取结论 只能判断这个数据完全不存在,但是不能完全判断其存在。 优势/劣势 优势 布隆过滤器存储空间和插入/查询时间都是常数。 Hash函数相互之间没有关系,方便由硬件并行实现。 布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。 劣势 误差率 难以删除 删除在布隆过滤器的值 通过引用计数来实现,也就是说在hash值所对应的向量值采取引用计数方式,如果某个hash值是这个向量所对应的索引,则给它加1。如果要删除这个hash值所对应的向量的话,就看其索引值是否为0.如果不是0,就不能删除,否则可以删除。 删除整个布隆过滤器,重新在添加数据。 代码实现 安装 mmh3 pip install mmh3 安装bitarray pip install

BitSet和布隆过滤器(Bloom Filter)

做~自己de王妃 提交于 2020-01-07 17:45:52
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 布隆过滤器 Bloom Filter 是由Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员。如果检测结果为是,该元素不一定在集合中;但如果检测结果为否,该元素一定不在集合中。因此Bloom filter具有100%的召回率。这样每个检测请求返回有“在集合内(可能错误)”和“不在集合内(绝对不在集合内)”两种情况,可见 Bloom filter 是牺牲了正确率和时间以节省空间。 当然布隆过滤器也有缺点,主要是误判的问题,随着数据量的增加,误判率也随着增大,解决办法:可以建立一个列表,保存哪些数值是容易被误算的。 Bloom Filter最大的特点是不会存在false negative,即:如果contains()返回false,则该元素一定不在集合中,但会存在一定的true negative,即:如果contains()返回true,则该元素可能在集合中。 Bloom Filter在很多开源框架都有实现,例如: Elasticsearch:org.elasticsearch.common.util.BloomFilter guava:com.google.common.hash.BloomFilter Hadoop:org

网络爬虫之url等高效率去重原理

陌路散爱 提交于 2020-01-07 17:18:38
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 布隆过滤器用于字符串去重复,比如网络爬虫抓取时URL去重、邮件提供商反垃圾黑名单Email地址去重。等等。用哈希表也可以用于元素去重,但是占用空间比较大,而且空间使用率只有50%。   布隆过滤器只占哈希表的1/8或1/4的空间复杂度,就能解决同样的问题,但是有一定的误判,而且不能删除已有元素。元素越多,误报率越大,但是不会漏报。对于还需要删除的布隆过滤器,还有Counter Bloom Filter,这个是布隆过滤器的变体,可以删除元素。 布隆过滤器的原理 布隆过滤器需要的是一个一维数组(和位图类似)和K个映射函数(和Hash表类似),在初始状态时,对于长度为m的位数组array,它的所有位被置0。    对于有n个元素的集合S={S1,S2...Sn},通过k个映射函数{f1,f2,......fk},将集合S中的每个元素Sj(1<=j<=n)映射为K个值{g1,g2...gk},然后再将位数组array中相对应的array[g1],array[g2]......array[gk]置为1:      如果要查找某个元素item是否在S中,则通过映射函数{f1,f2,...fk}得到k个值{g1,g2...gk},然后再判断array[g1],array[g2]...array[gk]是否都为1,若全为1

布隆过滤器(Bloom Filter)

∥☆過路亽.° 提交于 2020-01-07 17:16:42
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 基本概念 如果想判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定。链表、树、散列表(又叫哈希表,Hash table)等等数据结构都是这种思路。但是随着集合中元素的增加,我们需要的存储空间越来越大。同时检索速度也越来越慢,上述三种结构的检索时间复杂度分别为O(n),O(\log n),O(n/k)。 布隆过滤器的原理是,当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在。这就是布隆过滤器的基本思想。 优点 相比于其它的数据结构,布隆过滤器在空间和时间方面都有巨大的优势。布隆过滤器存储空间和插入/查询时间都是常数(O(k))。另外, 散列函数相互之间没有关系,方便由硬件并行实现。布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。 布隆过滤器可以表示全集,其它任何数据结构都不能; k和m相同,使用同一组散列函数的两个布隆过滤器的交并差运算可以使用位操作进行。 缺点 但是布隆过滤器的缺点和优点一样明显。误算率是其中之一。随着存入的元素数量增加,误算率随之增加。但是如果元素数量太少

布隆过滤器

吃可爱长大的小学妹 提交于 2019-12-27 00:20:42
布隆过滤器的原理: 布隆过滤器是一种多哈希函数映射的快速查找算法。它可以判断出某个元素肯定不在集合里或者可能在集合里,即它不会漏报,但可能会误报。通常应用在一些需要快速判断某个元素是否属于集合,但不严格要求100%正确的场合。 基本原理: 一个空的布隆过滤器是一个m位的位数组,所有位的值都为0。定义了k个不同的符合均匀随机分布的哈希函数,每个函数把集合元素映射到位数组的m位中的某一位。 添加一个元素: 先把这个元素作为k个哈希函数的输入,拿到k个数组位置,然后把所有的这些位置置为1。 查询一个元素(测试这个元素是否在集合里): 把这个元素作为k个哈希函数的输入,得到k个数组位置。这些位置中只要有任意一个是0,元素肯定不在这个集合里。如果元素在集合里,那么这些位置在插入这个元素时都被置为1了。如果这些位置都是1,那么要么元素在集合里,要么所有这些位置是在其他元素插入过程中被偶然置为1了,导致了一次“误报”。 一个布隆过滤器的例子见下图,代表了集合{x,y,z}。带颜色的箭头表示了集合中每个元素映射到位数组中的位置。元素w不在集合里,因为它哈希后的比特位置中有一个值为0的位置。在这个图里,m=18,k=3。 简单的布隆过滤器不支持删除一个元素,因为“漏报”是不允许的。一个元素映射到k位,尽管设置这k位中任意一位为0就能够删除这个元素,但也会导致删除其他可能映射到这个位置的元素

浅谈布隆过滤器Bloom Filter

馋奶兔 提交于 2019-12-16 17:15:28
先从一道面试题开始: 给A,B两个文件,各存放50亿条URL,每条URL占用64字节,内存限制是4G,让你找出A,B文件共同的URL。 这个问题的本质在于判断一个元素是否在一个集合中。哈希表以O(1)的时间复杂度来查询元素,但付出了空间的代价。在这个大数据问题中,就算哈希表有100%的空间利用率,也至少需要50亿*64Byte的空间,4G肯定是远远不够的。 当然我们可能想到使用位图,每个URL取整数哈希值,置于位图相应的位置上。4G大概有320亿个bit,看上去是可行的。但位图适合对海量的、 取值分布很均匀 的集合去重。位图的空间复杂度是随集合内最大元素增大而线性增大的。要设计冲突率很低的哈希函数,势必要增加哈希值的取值范围,假如哈希值最大取到了2 64 ,位图大概需要23亿G的空间。4G的位图最大值是320亿左右,为50亿条URL设计冲突率很低、最大值为320亿的哈希函数比较困难。 题目的一个解决思路是将文件切割成可以放入4G空间的小文件,重点在于A与B两个文件切割后的小文件要一一对应。 分别切割A与B文件,根据 hash(URL) % k 值将URL划分到k个不同的文件中,如A1,A2,...,Ak和B1,B2,...,Bk,同时可以保存hash值避免重复运算。这样Bn小文件与A文件共同的URL肯定会分到对应的An小文件中。读取An到一个哈希表中,再遍历Bn