BloomFilter算法,是一种大数据排重算法。在一个数据量很大的集合里,能准确断定一个对象不在集合里;判断一个对象有可能在集合里,而且占用的空间不大。它不适合那种要求准确率很高的情况,零错误的场景。通过牺牲部分准确率达到高效利用空间的目的。
场景一:假如有一个很大的表,通过字段key查询数据,操作很重;业务方请求时,传过来的key有很大一部分是不存在的;这种不存在的key请求就会浪费我们的查询资源。针对这种情况,我们可以引人BloomFilter算法,在请求key查询之前,使用BloomFilter匹配。如果不存在,就不用去查询了(正确率百分之百);如果存在,走原来的查询流程(有可能不存在的key混进去了)。
场景二:假如有一个很大的表,通过字段key判断是否存在,操作很重,如果存在就做一些操作,不存在就加入表中;可容许一定的误判。对应这种情况,我们也可以引入BloomFilter算法,通过key查询表判断存在否的方式可换成BloomFilter算法。如果存在,我们执行以前的逻辑(有一定的误判,业务也允许一定的错误);如果不存在,也执行以前的逻辑。
BloomFilter是由一个长度为n的bit数组S(Bitmap)和k个hash算法组成。 如果单独用Bitmap和一个hash则其碰撞太厉害,多次hash降低碰撞概率。
第一步:先使bit数组的初始值为0
第二步:添加值M,M经过k个hash算法计算后,得到:M1, M2 … Mk; 然后,使S[M1]=1,S[M2]=1... S[Mk]=1
第三步:判断值Y,Y经过k个hash算法计算后,得到:Y1,Y2... Yk。 然后,判断S[Y1],S[Y2] … S[Yk] 是否都为1。如果有一个不为1,那这个Y就一定是不存在的,以前没添加过;如果都为1,那这个Y可能存在,也可能其他值添加后,影响了这次判断的结果。
如果我们要移除值,怎么办呢?当前的结构是没法实现的,我们可以通过在加一个等长的数据,存放每个bit位设置为1的次数,设置一次加1,取消一次减一。