现在看来,将100亿个数据先存放到hashmap,然后再判断是否存在某个数,的确不是一个好方法。
首先,写的性能比较低;其次,所需的内存太大。
据统计,100亿个数据存入hashmap大概须要几百G的内存。

那有没有一个更好的实现办法呢?有,可以利用布隆过滤,即是本文即将先容的紧张内容。

什么叫布隆过滤

布隆过滤器(英语:Bloom Filter)是1970年由布隆提出的。
它实际上是一个很长的二进制矢量和一系列随机映射函数
布隆过滤器可以用于检索一个元素是否在一个凑集中。
它的优点是空间效率和查询韶光都远远超过一样平常的算法,缺陷是有一定的误识别率和删除困难。

php判断redis是否存在机能优化若何在100亿个数据中断定某个数据是否存在 Vue.js

布隆过滤的事理

下图表示有三个hash函数,比如一个凑集中有x,y,z三个元素,分别用三个hash函数映射到二进制序列的某些位上,假设我们判断w是否在凑集中,同样用三个hash函数来映射,结果创造取得的结果不全为1,则表示w不在凑集里面。

详细的操作流程如下:

第一步:开辟空间

开辟一个长度为m的位数组(或者称二进制向量),这个不同的措辞有不同的实现办法,乃至你可以用文件来实现。

第二步:探求hash函数

获取几个hash函数,前辈们已经发明了很多运行良好的hash函数,比如BKDRHash,JSHash,RSHash等等。
这些hash函数我们直接获取就可以了。

第三步:写入数据

将所须要判断的内容经由这些hash函数打算,得到几个值,比如用3个hash函数,得到值分别是1000,2000,3000。
之后设置m位数组的第1000,2000,3000位的值位二进制1。

第四步:判断

接下来就可以判断一个新的内容是不是在我们的凑集中。
判断的流程和写入的流程是同等的。

布隆过滤的PHP实现

由于Redis实现了setbit和getbit操作,天然适宜实现布隆过滤器,redis也有布隆过滤器插件,以是这里利用php+redis实现布隆过滤器。

首先定义一个hash函数凑集类,这些hash函数不一定都用到,实际上32位hash值的用3个就可以了,详细的数量可以根据你的位序列总量和你须要存入的量决定,上面已经给出最佳值。

接着便是连接redis来进行操作

上面定义的是一个抽象类,如果要利用,可以根据详细的业务来利用。
比如下面是一个过滤重复内容的过滤器。

参考

https://blog.csdn.net/leeafay/article/details/78681534

http://imhuchao.com/1271.html