从Hash 到布隆过滤器
Hash表
哈希表是存储集合常用的数据结构。添加元素时,我们将元素通过哈希函数映射到哈希表的某个存储单元上,并把该元素保存在此单元;要判断元素是否属于集合,可以使用相同的哈希函数找到该元素对应的存储单元,如果该单元为空,说明元素还未添加进集合;如果该单元不空,则取出内容与该元素进行比较,只有经过比较相同后才断定该元素属于集合。可以看出,哈希表最消耗空间的部分是将元素保存到存储单元上。因为不同元素通过哈希函数有可能对应相同的单元,所以我们必须将元素保存到单元上,才能保证有足够的信息准确区分对应相同单元的不同元素。
信息指纹
在字处理软件中,需要检查一个英语单词是否拼写正确(也就是要判断它 是否在已知的字典中);在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上;在网络爬虫里,一个网址是否被访问过等等。我们都需要一种信息来标记我们所查过或者我们被访问过的东西,而且这种信息都是唯一的,区别与其他的一种信息。所以我们将任何一段信息文字,都可以对应一个不太长的随机数,作为区别它和其它信息的“指纹”。
在爬虫中网址的消重上,需要在哈希表中纪录已经访问过的网址(URL)。假设现在要存储在哈希表中如果以字符串的形式直接存储网址,既费内存空间,又浪费查找时间。为什么会是这样呢?答案如下:
一方面,现在的网址一般都较长,多的达到一百甚至几百个字符。而哈希表的存储效率一般只有 50%(个人理解:为了避免高碰撞,一般哈希存到一半时都翻倍或采取其他策略),所以很费内存;
另一方面,由于比较费空间,假设存储的URL大概有500M,由于哈希的存储效率,实际就需要1G空间存储,即使把这些网址放到了计算机的内存中,由于网址长度不固定,以字符串的形式查找的效率会很低(个人理解:虽然说哈希的查找效率为O(1),但是由于字符串长度不固定,在查找某个特定串的时候无法根据偏移量直接找到或者找到也应该比较费劲,如果忽略串的长度不固定,采用统一长度的内存存储每个串,那又太费空间了,所以很麻烦)。
那么怎么办?我们应该想法既让空间节省下来(不直接存储字符串),又能在查找上提高效率?
这就需要有一种数据结构既能够能将大量的数据的内存存储需要降下来,同时也也能提供也有很高的查询效率,所以就有了布隆过滤器。布隆过滤器中要先了解信息指纹是什么,后面就是我们要介绍的。
现假定网址的平均长度为一百个字符,那么存贮 200 亿个网址本身至少需要 2 TB,即两千 GB 的容量,考虑到哈希表的存储效率一般只有 50%,实际需要的内存在 4 TB以上,这么大的空间查找起来也怪不容易的。因此如果我们能够找到一个函数,将这 200 亿个网址随机地映射到128 二进位即 16 个字节的整数空间,这样每个网址只需要占用 16 个字节而不是原来的一百个,这就能把存储网址的内存需求量降低到原来的 1/6。这个16 个字节的随机数,就称做该网址的信息指纹(Fingerprint)
Bitmap数据结构
因为布隆过滤器是位图+哈希表构成的,所以他的基础知识一定要知道,位图是什么?
位图就是bitmap的缩写。所谓bitmap,就是用每一位来存放某种状态,适用于大规模数据,但数据状态又不是很多的情况。通常是用来判断某个数据存不存在的。
unsigned int bit[N];
在这个数组里面,可以存储 N * sizeof(int)个数据,但是最大的数只能是N * sizeof(int) - 1。假如,我们要存储的数据范围为0-15,则我们只需要使得N=1
数据为【5,1,7,15,0,4,6,10】,则存入这个结构中的情况为
布隆过滤器(简单的介绍布隆过滤器)
我们以一个实例来说明他布隆过滤器 是如何构造的;
1 垃圾邮件过滤中的黑白名单
爬虫(Crawler)的网址判重模块
下面详细的阐述一个例子,先是插入:
1 为了存储一亿个电子邮件地址
2 建立一个含有十六亿二进制比特,也就是两亿字节
3 将十六亿的比特全部设置为0
4 我们用八个不同的哈希函数,以电子邮件地址为键,算出值,有8个(也许不是数字)
5 我们再一个哈希函数,分别以这8个值为键,会得到8个数值(范围为1到十六亿的某个数字)
6 以上一步算出的8个数值为下标,将这8个位置的二进制都设置为1(存储了一个地址)
下一篇会有对布隆过滤器的详细分析以及实现
<!--EndFragment-->
相关推荐
布隆过滤器基于多个哈希函数,将元素映射到一个固定大小的位数组中。当一个元素插入时,会通过多个不同的哈希函数将其映射到数组的不同位置,并将这些位置设为1。查询时,如果所有对应位置都是1,则认为该元素可能...
布隆过滤器主要由一个位数组(bit array)和多个不同的哈希函数组成。当一个元素被添加到过滤器时,它会通过所有这些哈希函数计算出几个位索引,并将这些位置为1。检查一个元素是否存在于过滤器中时,同样使用相同的...
在Java中实现布隆过滤器,主要涉及到以下几个关键知识点: 1. **位数组**:布隆过滤器的核心是一个很长的位数组,初始化时所有位都设置为0。位数组的大小是根据预期要存储的元素数量和允许的误判率来确定的。 2. *...
布隆过滤器的基本原理是将所有可能存在的元素映射到一个固定大小的位数组(bit array)上。这个位数组最初全部设置为0。当一个元素插入时,会通过多个独立的哈希函数计算出几个不同的位置,并将这些位置的值设为1。...
1. **基本原理**:布隆过滤器利用多个哈希函数将元素映射到一个固定大小的位数组中。每个元素会通过多个不同的哈希函数,将对应的位设置为1。由于使用了多个哈希函数,可能会有冲突,但这种设计使得插入和查询操作...
布隆过滤器,大家学过数据结构的应该都清楚,一般的字典树要实现嵌入和查找都内存的消耗非常大,布隆过滤器有BloomFilter,string, BKDRHash, APHash, DJBHash> bf五个参数你要查找的元素个数,查找元素类型,三个...
布隆过滤器的基本原理是,当一个元素被添加到集合中时,通过多个哈希函数将其映射到二进制向量的多个位置,将这些位置设置为1。如果在查询时,所有映射位置都是1,那么元素可能存在,但如果至少有一个位置是0,则...
布隆过滤器的原理是将元素抽象为该元素多个哈希函数的结果,并将这些结果存储在位数组中,以便快速判断元素是否存在。 布隆过滤器的优点是存储元素使用空间更少,并且判断效率更高(时间复杂度O(k),k为哈希函数的...
《网络游戏-基于指纹多重哈希布隆过滤器的网络取证内容溯源方法》是针对网络游戏环境中的网络取证技术进行深入探讨的资料。这份资料的核心在于利用指纹多重哈希布隆过滤器来实现网络内容的溯源,这在网络安全和司法...
布隆过滤器是一种概率数据结构,用于判断一个元素是否可能在一个集合中存在。它通过使用位数组和几个独立的哈希函数来实现,具有高效、节省空间的特点,但可能会产生假阳性错误,即误判一个不在集合中的元素为在集合...
布隆过滤器的工作原理是利用多个哈希函数将元素映射到一个固定大小的位数组中。这些哈希函数通常是独立且随机分布的,可以避免冲突并使得数据分布均匀。当一个元素插入时,它会被多个哈希函数映射,并在对应的位数组...
1. **基本结构**:布隆过滤器是一个很长的二进制数组和几个独立的哈希函数。数组初始全为0,哈希函数是随机且独立的。 2. **插入操作**:当插入一个元素时,会使用每个哈希函数计算出对应的数组下标,然后将这些...
4. **不支持删除操作**:一旦元素被添加,无法从布隆过滤器中移除,因为可能会导致其他元素的哈希位被清零。 ### 安装Redis布隆过滤器插件 1. **获取插件**:首先,你需要从官方仓库或者GitHub等平台下载Redis的...
规则库中包含了用于哈希函数计算的参数,这些参数会影响到布隆过滤器的性能,包括误判率和过滤率。在硬件实现时,这些规则库参数也需要被适配到硬件逻辑中,以确保硬件电路能够正确地生成和验证布隆过滤器。 在处理...
布隆过滤器的核心思想在于使用多个哈希函数将元素映射到一个位数组上,多个哈希函数可以减少冲突,但也会增加误判的可能性。因此,在实际应用中,需要根据数据规模和误判容忍度来选择合适的参数。 总结,PHP结合...
2. **位数组**:布隆过滤器的核心是一个巨大的位数组,所有哈希函数的输出都会被用来设置这个数组中的位。位数组的大小直接影响过滤器的误报率和存储需求。 3. **插入操作**:将元素插入过滤器时,通过每个哈希函数...
布隆过滤器的基本原理是使用多个不同的哈希函数将元素映射到一个固定大小的位数组中。每个位置初始为0,当一个元素被添加时,对应的哈希值所对应的位被设置为1。如果要查询一个元素是否存在,就检查所有哈希函数对应...
布隆过滤器的工作原理是基于哈希函数和位数组的。它将输入元素通过多个哈希函数映射到位数组中的不同位置,然后将这些位置设置为1。在查询时,只需要对输入元素进行哈希映射,并检查相应的位数组位置是否为1,从而...
布隆过滤器的基本原理是通过多个独立的哈希函数将元素映射到一个固定大小的位数组上。每次插入元素时,都会用这些哈希函数计算出位置并设置位数组中的对应位为1。查询时,如果所有哈希函数计算出的位置都是1,那么...
3. **插入操作(Insertion)**:当向布隆过滤器添加元素时,会用每个哈希函数计算元素的哈希值,并将对应的位数组位设为1。这个过程是不可逆的,因为无法从位数组的设置推导出原始元素。 4. **查询操作(Query)**...