一、所要解决的问题
1.1、问题
- 现在有100亿个非法的URL,假设,一个URL是64字节,在客户访问时如果访问的是这100亿里面的URL,则无法成功访问;
1.2、问题分析
- 为了能快速查找到,我们一般都会想到利用哈希表,将每一个URL存到HashSet。但是这样做需要的空间大小是6400亿个字节,也就是640G;如果将这么大的数据放到硬盘里面存储,那么访问速度就会特别慢。如果放到内存里面进行访问,则就需要很多台大型服务器去支持。这显然会增加成本;因此我们使用布隆过滤器;
二、布隆过虑器的使用
2.1、位图
- 在设计布隆过滤器之前,我们得先了解一下位图;
- 位图,就是用每一位来存放某种状态,适用于大规模数据,
2.2、位图的操作
int[] arr = [10];//通过计算可知,该数组的位数是320位;
//想对第178位进行操作
int i = 178;
//将第178位改成1
int numIndex = i/32;//计算出第178位在数组中的下标;
int bitIndex = i%32;//计算出第178在上面计算出来的下标的数据的哪一位上;
//拿到第178位的状态
int sys = ((arr[numIndex] >> bitIndex) & 1);
//更改第178位为0
sys = arr[numIndex] & (~(1 << bitIndex));
//更改第178位为1
sys = arr[numIndex] | (1 << bitIndex);
2.3、布隆过滤器的特点
- 只能做增加、查找工作;
- 不能进行删除;比如删除已经加进到黑名单里面的某个URL,这个不能实现;
- 布隆过滤器还会在失误率;(这个失误率可以通过人为控制)
2.4、布隆过滤器中的位图设计原则
这一部分出现的m和k在2.5介绍如何去计算
- 遍历要加进黑名单的每一个URL。并且对每一个URL计算出K个哈希值,对求出来的哈希值模上m,然后将求模得到的值作为位置下标,并且将位图上的该位置状态改成1;(如果后面计算得到的位置下标前面重复,则无需再改);
2.4.1、这样设计可以达到的效果
- 如果你输入的URL在这个黑名单里面,则一定可以检测出来;
- 也许会把输入的合法的URL当成非法的URL,从而阻止访问;(这个就是布隆过滤器存在的失误)。出现这个问题的原因可能是位图长度过短造成的。
- 注意事项:如果位图过短,数据量过大,可能会存在将位图上的每一位状态都改成1的情况,这种情况下,无论你输入什么URL,都会当成黑名单里面的URL。
2.5、m和k的计算方式
k值计算出来后需要向上取整。
2.6、通过图像,分析失误率和m、k之间的关系
- (图一)随着m的增大,失误率会越来越低;
- (图二)当m固定时,随着k的增大,失误率会先降低,然后再升高,所以,要注意把控k的取值范围;