Apache spark Spark RDD.aggregate vs RDD.reduceByKey?
我有和RDD[String],每行包含一个单词。目前的规模非常小,只有10-20k条线路,但目标是将其扩展到数亿条线路。我遇到的问题是,即使对于这个小数据集,执行map/reduceByKey操作也要花费惊人的时间。我运行以下命令:Apache spark Spark RDD.aggregate vs RDD.reduceByKey?,apache-spark,Apache Spark,我有和RDD[String],每行包含一个单词。目前的规模非常小,只有10-20k条线路,但目标是将其扩展到数亿条线路。我遇到的问题是,即使对于这个小数据集,执行map/reduceByKey操作也要花费惊人的时间。我运行以下命令: val wordcount = filtered.map(w => (w,1)).reduceByKey(_ + _) 对于16780条线路,在2 GHz i7 8 GB RAM机器上需要12321毫秒。我发现有一种称为聚合的方法可能更高效,因此速度更快:
val wordcount = filtered.map(w => (w,1)).reduceByKey(_ + _)
对于16780条线路,在2 GHz i7 8 GB RAM机器上需要12321毫秒。我发现有一种称为聚合的方法可能更高效,因此速度更快:
aggregate[U: ClassTag](zeroValue: U)(seqOp: (U, T) => U, combOp: (U, U) => U): U
我不太明白如何在我的案例中实现这一点。我想应该是这样的
aggregate(collection.immutable.Map)(??)
所以我的问题是
1)使用聚合而不是reduceByKey有意义吗
2)如果是,将如何实现它?我想,最快的应该是
countByValue
:
将此RDD中每个唯一值的计数作为(值,计数)对的映射返回。最后的合并步骤在主机上本地进行,相当于运行单个reduce任务
用法很简单:
val wordcount = filtered.countByValue
此方法的实现应回答第二个问题:)
顺便说一下,reduceByKey
不应该花那么长时间。看起来预计算(即过滤)占用了这12秒钟的大部分时间。要验证它,请在计数前保持RDD:
val persisted = filtered.persist
val wordcount = persisted.countByValue
<代码> CoptByValue<代码>将是最快的方法,但是它的实现使用哈希映射并合并它们,所以如果你有大量的数据,这种方法可能无法很好地扩展(尤其是当你考虑有多少问题已经在内存中闪现)。您可能希望使用map reduce中的标准计数方法,即将线和1映射为对,然后
reduceBykey
如下所示:
val wordCount = filtered.map((_,1)).reduceByKey(_+_).collect()
你也可以考虑使用<代码> CurtByValueOndox一般来说,当处理数据时,这个近似值通常是足够好的,到目前为止是最有效的方法(尽管它仍然使用散列映射,所以用许多独特的词,你仍然可以失败)。如果无法获得<代码> CurtByValue<代码>,可以考虑使用这个。
persist/cache
仅当您要多次使用缓存的RDD时才有帮助,否则它们实际上会降低您的程序运行速度谢谢!在之前的过程中确实出现了一些问题,但我修复了这个问题,并切换到countByValue,现在似乎运行良好。出于好奇,我试图了解Spark,你指的是@aaronman的哪些内存问题?有什么我应该注意的吗?@langkilde不一定是任何具体的东西,只是在生产中,许多人似乎很难在不破坏大量数据的情况下运行完全正确的spark作业。由于spark还很年轻,我希望这些问题在以后的版本中得到解决