【问题标题】:How to pass one RDD in another RDD through .map如何通过.map在另一个RDD中传递一个RDD
【发布时间】:2016-01-16 15:15:17
【问题描述】:

我有两个 rdd,我想为 rdd1 的每个项目对 RDD2 项目进行一些计算。所以,我在用户定义的函数中传递 RDD2,如下所示,但我收到类似 rdd1 cannot be passed in another rdd 的错误。如果我想对两个 rdd 执行操作,我能知道如何实现吗?

例如:

RDD1.map(line =>function(line,RDD2))

【问题讨论】:

    标签: scala apache-spark


    【解决方案1】:

    如错误所示,Spark 不支持嵌套 RDD。通常你必须通过重新设计你的算法来绕过它。

    如何做到这一点取决于实际用例、function 中究竟发生了什么以及它的输出。

    有时RDD1.cartesian(RDD2),对每个元组进行操作,然后通过键减少将起作用。有时,如果你有 (K,V) 输入两个 RDD 之间的连接将起作用。

    如果 RDD2 很小,您始终可以在驱动程序中收集它,将其设为广播变量并在 function 中使用该变量而不是 RDD2

    @编辑:

    例如,假设您的 RDD 保存字符串,function 将计算来自RDD 的给定记录在RDD2 中出现的次数:

    def function(line: String, rdd: RDD[String]): (String, Int) = {
       (line, rdd.filter(_ == line).count)
    } 
    

    这将返回一个RDD[(String, Int)]

    想法1

    您可以使用 RDD 的 cartesian 方法尝试使用 cartesian product

    val cartesianProduct = RDD1.cartesian(RDD2) // creates RDD[(String, String)]
                               .map( (r1,r2) => (r1, function2) ) // creates RDD[(String, Int)]
                               .reduceByKey( (c1,c2) => c1 + c2 ) // final RDD[(String, Int)]
    

    这里function2 接受r1r2(它们是字符串),如果它们相等则返回1,否则返回0。最终的映射将产生一个RDD,其中包含元组,其中键是来自r1 的记录,值是总计数。

    问题 1:如果您在 RDD1 中有重复的字符串,这将不起作用。你得好好想想。如果RDD1 记录有一些独特的ID,那就完美了。

    问题 2:这确实会创建很多对(对于两个 RDD 中的 100 万条记录,它会创建大约 5000 亿对),会很慢并且很可能会导致很多 shuffling

    创意2

    我不明白您对 RDD2 大小 lacs 的评论,所以这可能有效,也可能无效:

    val rdd2array = sc.broadcast(RDD2.collect())
    val result = RDD1.map(line => function(line, rdd2array))
    

    问题:这可能会破坏您的记忆。在driver 上调用collect(),来自rdd2all 记录将被加载到驱动程序节点的内存中。

    想法3

    根据用例的不同,还有其他方法可以克服这个问题,例如brute force algorithm for Similarity Search 与您的用例相似(双关语不是有意的)。对此的替代解决方案之一是Locality Sensitive Hashing

    【讨论】:

    • 感谢您的回复。我有一个 RDD 中的用例,我有数百万行和 200 多列,而在另一个 rdd 中我有很多记录和列。我需要从 RDD1 中获取每一行,并且需要对整个 RDD2 进行一些比较和计算。为了实现这一点,我正在考虑在 RDD1 中传递这个 RDD2。但是如果我们不能在 Spark 中支持嵌套 RDD,那么如何克服这个问题。
    • @RaghavendraKulkarni 用一个例子扩展了我的答案
    • @MateuszDymczyk, "lac" == 100,000(在印度使用)。
    • 非常感谢 Mateusz Dymczyk
    • @RaghavendraKulkarni 没问题。它解决了你的问题吗?如果是的话,如果你接受这个作为答案会很酷。如果不是,如果您提供更多详细信息,我们可以考虑一些不同的东西:-)
    猜你喜欢
    • 2017-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-23
    • 2016-04-28
    • 2016-08-23
    • 2017-06-17
    • 1970-01-01
    相关资源
    最近更新 更多