type
status
date
slug
summary
tags
category
icon
password

overview

许多人都有过这样的经历:注册新的社交平台或是游戏账号时,需要输入一个独一无二的名字,可输入了很多。却发现系统总返回类似user name has existed这样的信息;注册过的用户可能有成百上千万,应用是如何快速判断我们输入的username是否已经被注册过了呢?
让我们将问题进一步陈述:如何在一堆数据中快速判断某一个数据是否存在?
大多数人的第一反应是二分法,二分法也确实可以用来处理这个需求,但是二分法logn的时间复杂度使得应用判断的依旧不够快。
于此,我们引入了今天的主角—bloom filter(布隆过滤器)
 

WHAT

bloom filter是一种高效的数据筛选结构,可以用来快速判断某一个数据是否存在于一个数据集中;这里讲的高效,是时间与空间两方面的。
 

HOW

bloom filter主要涉及存储与查找两个过程;
其实现机制主要依靠两个东西:哈希函数与byte数组;
byte数组所有元素初始值均为0,其后存入的元素按照一定的映射规则,将对应的元素置为1,其后判断是否存在该元素时,按照相同的映射规则,找到对应的元素,看其是否为1;
 
以下是存储过程的大致流程:
  1. 我们要有一个byte数组,其所有元素为0,方便起见,假设数组大小为10;
notion image
  1. 准备一组哈希函数,这里方便起见,假设为三个:h1,h2,h3;
  1. 定义一组映射规则,用于将哈希后的结果映射到byte数组下标,比如:
h1(imput)%10=3
  1. 传入input,假定input为lover,以下是映射过程:
h1(”lover”)%10=1
h2(”lover”)%10=7
h3(”lover”)%10=9
  1. 将以上映射出来的index所对应的元素置1;
至此,我们实现了存储的过程;
 
查找的过程便是判断对应下标的元素是否为1,假如有一个不为1,我们就认为这个元素不存在,否则认为它存在;
 

Note

bloom filter判断元素是否存在的功能十分强大,但是它有一个缺陷,有时会把不存在的数据判断为存在,这个缺陷本质是因为哈希碰撞,导致两个input映射之后的元素相同,我们可以通过增大byte数组的大小来降低这种概率;(注意:存在的数据是绝对不会被判断为不存在的!)
 

Implement

下面是Go语言bloom filter的简单实现:
 

Application

bloom filter的应用十分广泛,除了上面说过的用户名判断,还包括但不限于:
防短信邮件轰炸,以太坊收据树中用于快速查询,防止缓存击穿…
 
关于本站,关于我欲望的满足
Alex
Alex
某不知名青年|web2.5人士|喜欢猫与美少女
公告
type
status
date
slug
summary
tags
category
icon
password
有事请邮箱联系:alexwu7@outlook.com
🚀🚀🚀