【问题标题】:how to check RDD is empty efficiently?如何有效地检查 RDD 是否为空?
【发布时间】:2017-02-22 09:30:41
【问题描述】:

在使用filter 之后,我使用了spark RDD.isEmpty。但是我认为大数据需要花费很多时间,因为isEmptytake(1)的动作操作。

这里是示例代码。

val data = sc.parallelize(Seq(("a", 1), ("a", 2), ("b", 2), ("b", 3), ("c", 1)))
.reduceByKey(_+_)
.filter(_._2 > 5)
//Array[(String, Int)] = Array()

if(!data.isEmpty()){
    //running code...
}

有没有一种有效的方法来检查数据值是否为空?

【问题讨论】:

  • 为什么不在 if 循环中使用 data.count()?
  • 我认为它不适合大数据。
  • 但我认为大数据需要花费很多时间 这感觉更像是一种直觉。您是否对代码进行了基准测试?这是真正的瓶颈吗?
  • 您的整体执行时间得到改善的原因是 Spark 实际上并没有做任何事情。请记住,RDD 是惰性的,并且您的 parallelize/reduceByKey/filter 操作将不会运行,直到最后有一个操作。 isEmpty 是一种非常快的操作,与您可以为此类检查执行的任何其他操作相比。
  • @S.Kang isEmpty 在内部使用take(1),因此它们在运行时基本相同。无论哪种情况,它们都非常便宜,需要时间的是对 RDD 的评估,因此数据的加载和任何其他转换,特别是需要 shuffle 的广泛操作,都会产生更大的影响。

标签: performance scala apache-spark


【解决方案1】:

RDD.isEmpty 是最有效的。它做的工作量尽可能少。

请记住,RDD 不是数据,它是一个执行计划。如果没有实际评估,就无法检查 RDD 中是否有数据,因此您必须执行操作并检查结果。

如果您需要在最终操作之前检查 RDD 是否为空,您可以先persist 它来缓存中间状态,这样就不需要在以后的作业中重新评估它。

【讨论】:

    【解决方案2】:

    正如您已经说过的,rdd.isEmpty 是一个动作,除非您重构代码以删除 if 条件(使用更多函数式样式而不是命令式样式),否则无法消除低效率。正如已经建议的那样,最简单的解决方案可能是在调用 isEmpty 之前使用缓存 rdd,这样如果您有足够的缓存内存,转换将只执行一次。

    我不知道,作为“if(data.isEmpty())”的一部分,你想要什么,我能给出的唯一建议是,rdd.map、rdd.foreach 等即使对于空 RDD 也是完全有效的. “if(data.isEmpty())”可能是解决方案的一种方法。如果您能更详细地说明问题,我们可以建议一种功能性方法。

    【讨论】:

    • 感谢您的回复!我想知道如何使用cacheval data = sc.parallelize(Seq(("a", 1), ("a", 2), ("b", 2), ("b", 3), ("c", 1))) .reduceByKey(_+_) .filter(_._2 > 5).cache 是你的意思吗??
    • 这正是我的意思。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    • 2013-05-28
    • 2010-12-20
    • 2011-08-01
    相关资源
    最近更新 更多