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

Apache spark Spark和BloomFilter共享 我有一个巨大的RDD(源代码),我需要从它中创建一个Bloom Filter数据,因此对用户数据的后续更新将只考虑真正的“差异”,不重复。,apache-spark,bloom-filter,Apache Spark,Bloom Filter,看起来BloomFilter的大多数实现都是不可序列化的(尽管可以很容易地修复),但我希望工作流略有不同: 处理每个分区,并为每个分区创建相应BloomFilter的实例。对于每个BloomFilter对象,将其写入某个二进制文件中。实际上,我不知道如何处理整个分区—RDD上有mapPartition函数可用,但这要求我返回一个迭代器。也许我可以使用传递的迭代器,创建一个BloomFilter实例,将其写入某个地方,并将指向创建文件的链接作为一个迭代器返回 在主节点上-使用该处理的结果(文件路径

看起来BloomFilter的大多数实现都是不可序列化的(尽管可以很容易地修复),但我希望工作流略有不同:

  • 处理每个分区,并为每个分区创建相应BloomFilter的实例。对于每个BloomFilter对象,将其写入某个二进制文件中。实际上,我不知道如何处理整个分区—RDD上有
    mapPartition
    函数可用,但这要求我返回一个迭代器。也许我可以使用传递的迭代器,创建一个BloomFilter实例,将其写入某个地方,并将指向创建文件的链接作为一个
    迭代器返回
  • 在主节点上-
    使用该处理的结果(文件路径列表),读取这些文件并聚合内存中的过滤器。然后将响应写入二进制文件
  • 我不知道正确的方法:

    • 从传递给
      mapPartitions
    • 使用
      consume
      读取第二阶段中文件的内容(当我有一个带有文件路径的RDD时,我必须使用
      SparkContext
      读取它们-看不出这是怎么可能的)

    谢谢

    breeze
    实现不是最快的,但它具有常见的Spark依赖项,可以与
    简单聚合一起使用

    import breeze.util.BloomFilter
    //调整值以适合您的情况
    val numBuckets:Int=100
    val numHashFunctions:Int=30
    val rdd=sc.parallelize(顺序(“a”、“d”、“f”、“e”、“g”、“j”、“z”、“k”),4)
    val bf=rdd.aggregate(新的BloomFilter[String](numBuckets,numHashFunctions))(
    _ += _, _ |= _
    )
    bf.包含(“a”)
    
    Boolean=true
    
    bf.contains(“n”)
    
    Boolean=false
    
    在Spark 2.0+中,您可以使用DataFrameStatFunctions.bloomFilter

    val df=rdd.toDF
    val预期数值:长=1000
    val fpp:Double=0.005
    val sbf=df.stat.bloomFilter($“值”,预期的numitems,fpp)
    sbf.可能包含(“a”)
    
    Boolean=true
    
    sbf.可能包含(“n”)
    
    Boolean=false
    

    实现也可以工作,并且可以类似于
    breeze
    实现来使用。

    val sbf=df.stat.bloomFilter($“value”,expectedNumItems,fpp)中的$“value”是类
    的对象,换句话说,它是要在其上创建bloomFilter的列<代码>$
    相当于
    org.apache.spark.sql.functions.col
    。例如,在spark中使用时,必须将Bloom筛选器设置为广播变量,否则每个任务的开销将过大。广播变量在每个执行器中广播一次,否则,bloomfilter将在每个任务中传输一次(或为每个任务执行而构建)。@YoYo除非在阶段之间重复使用数据,或者您担心反序列化成本,否则广播筛选器没有充分的理由。@YoYo实际上不是这样。仅引用《编程指南》,Spark会自动广播每个阶段中任务所需的公共数据。以这种方式广播的数据以序列化形式缓存,并在运行每个任务之前进行反序列化。