Spark和BloomFilter共享

时间:2016-12-09 02:27:40

标签: apache-spark bloom-filter

我有一个巨大的RDD(源代码),我需要从中创建一个BloomFilter数据,因此对用户数据的后续更新将只考虑真正的“差异”,没有重复。

看起来BloomFilter的大多数实现都是不可序列化的(虽然可以很容易地修复),但我想要稍微不同的工作流程:

  1. 处理每个分区并为每个分区创建适当的BloomFilter实例。对于每个BloomFilter对象 - 将其写入某个二进制文件。我实际上并不知道如何处理整个分区 - 在RDD上有mapPartition函数可用,但是我希望我返回一个迭代器。也许我可以使用传递的迭代器,创建BloomFilter的实例,将其写入某处并将链接作为Iterator.singleton[PathToFile]返回到创建文件?
  2. 在主节点上 - consume处理结果(文件路径列表),读取这些文件并在内存中聚合BloomFilters。然后将响应写入二进制文件。
  3. 我不知道正确的方法:

    • 在传递给mapPartitions
    • 的函数中,在群集支持的FS中创建文件(可以是HDFS,S3N或本地文件)
    • 使用consume读取第二阶段文件的内容(当我有一个包含文件路径的RDD时,我必须使用SparkContext来阅读它们 - 看不到怎么可能)。

    谢谢!

1 个答案:

答案 0 :(得分:4)

breeze实现不是最快的,但它带有常见的Spark依赖项,可以与simple aggregate一起使用:

import breeze.util.BloomFilter

// Adjust values to fit your case
val numBuckets: Int = 100
val numHashFunctions: Int = 30

val rdd = sc.parallelize(Seq("a", "d", "f", "e", "g", "j", "z", "k"), 4)
val bf = rdd.aggregate(new BloomFilter[String](numBuckets, numHashFunctions))(
  _ += _, _ |= _
)

bf.contains("a")
Boolean = true
bf.contains("n")
Boolean = false

在Spark 2.0+中,您可以使用DataFrameStatFunctions.bloomFilter

val df = rdd.toDF

val expectedNumItems: Long = 1000 
val fpp: Double = 0.005

val sbf = df.stat.bloomFilter($"value", expectedNumItems, fpp)

sbf.mightContain("a")
Boolean = true
sbf.mightContain("n")
Boolean = false

Algebird实施也可以使用,并且可以与breeze实施类似地使用。