代码-布隆过滤器

一、作用

用来判断海量数据中是否存在指定值。

二、原理

将容器中的所有值求hashcode然后根据hashcode找,类似于hashmap,但不同的是这里只比较hash值,没有hash值相同之后的进一步精确匹配。
所以出现hash碰撞时,不能确定是否真的存在,此时可以使用不同的hash算法对数组中元素设置多个值,然后对每个值进行匹配。所以只要算法够多,误判几率就越低。

三、应用场景

Hbase就使用布隆过滤器来找rowkey,也会有误判的情况,本来没有,但返回有,此时无非就是遍历一个hfile而已,白搜了一个文件。可以接受。
新老用户判断
爬虫

四、使用

1. Hbase使用的是guava中的api

BloomFilter也是相当于一个容器,只不过这个容器里会对放入的元素求多个hashcode,然后把这些hashcode作为这个元素的下标。所以使用BloomFilter时,先创建BloomFilter对象,然后把元素put进去。然后就可以使用mightContain()判断是否存在了。

scala代码中一定要注意,BloomFilter.create[String]要加泛型,不然会报trying to do lub/glb of typevar ?Thttps://stackoverflow.com/questions/40585069/guava-bloomfilter-error-in-scala-compiler-trying-to-do-lub-glb-of-typevar-t

import com.google.common.base.Charsets
import com.google.common.hash.{BloomFilter, Funnels}

object 布隆过滤器 {
  def main(args: Array[String]): Unit = {
    //  样本
    val arr: Array[String] = Array("asdf", "qw", "qwe", "qwer", "aa", "zxc", "zz", "bb")
    //  创建bloomFilter,类型、可能的数据量(必须比实际数据量大,但一般都是实际量的10倍以上)、误判几率
    val bloomFilter: BloomFilter[String] = BloomFilter.create[String](Funnels.stringFunnel(Charsets.UTF_8), 100000, 0.000001)
    //  将样本中元素put到bloomFilter
    arr.foreach(bloomFilter.put(_))
    //  判断指定元素是否存在
    println(bloomFilter.mightContain("qw"))
    println(bloomFilter.mightContain("123"))
  }
}

2. 使用hadoop中的布隆过滤器工具类,这个不需要额外导包,sparksql的包中就有,core没有

object hadoop布隆过滤器 {
  def main(args: Array[String]): Unit = {
    //  样本
    val arr: Array[String] = Array("asdf", "qw", "qwe", "qwer", "aa", "zxc", "zz", "bb")
    val bloomFilter = new BloomFilter(100000,4,1)
    arr.foreach(ele => bloomFilter.add(new Key(ele.getBytes())))
    println(bloomFilter.membershipTest(new Key("qw".getBytes())))
    println(bloomFilter.membershipTest(new Key("12".getBytes())))
  }
}

在spark中使用,有2个问题:

  1. 创建bloomFilter 时,需要获取所有样本的集合,而样本的数据是分布式的,所以要么collect到driver,要么把bloomFilter 作为累加器广播出去。
  2. 需要把bloomFilter 对象广播出去,而因为bloomFilter 是hadoop提供的,实现了writeable接口,没有实现serializable接口,MR可以序列化,spark不能。所以会报无法序列化的错。因为spark默认用jdk的序列化框架,而jdk序列化框架的标记就是serializable。此时,可以用spark的序列化框架kryo。当然也可以写个子类实现serializable。
    在这里插入图片描述
    ==》
    使用kryo,能自动将driver中的共享变量序列化
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值