我有一个巨大的RDD(源代码),我需要从中创建一个BloomFilter数据,因此对用户数据的后续更新将只考虑真正的“差异”,没有重复。
看起来BloomFilter的大多数实现都是不可序列化的(虽然可以很容易地修复),但我想要稍微不同的工作流程:
mapPartition
函数可用,但是我希望我返回一个迭代器。也许我可以使用传递的迭代器,创建BloomFilter的实例,将其写入某处并将链接作为Iterator.singleton[PathToFile]
返回到创建文件?consume
处理结果(文件路径列表),读取这些文件并在内存中聚合BloomFilters。然后将响应写入二进制文件。我不知道正确的方法:
mapPartitions
consume
读取第二阶段文件的内容(当我有一个包含文件路径的RDD时,我必须使用SparkContext
来阅读它们 - 看不到怎么可能)。谢谢!
答案 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
实施类似地使用。