由于性能测量,我想逐步执行为scir编写的scala程序,即
execute first operator; materialize result;
execute second operator; materialize result;
...
等等。原始代码:
var filename = new String("<filename>")
var text_file = sc.textFile(filename)
var counts = text_file.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey((a, b) => a + b)
counts.saveAsTextFile("file://result")
所以我希望var counts = text_file.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey((a, b) => a + b)
的执行是逐步的。
在每个操作员正确的方式之后调用counts.foreachPartition(x => {})
吗?
或者用saveAsTextFile()
写一个/ dev / null是一个更好的选择吗?为此目的,火花实际上有类似NullSink的东西吗?我无法使用saveAsTextFile()
写入/ dev / null,因为/ dev / null已经存在。有没有办法覆盖spark结果文件夹?
每个操作后的临时结果是否应该使用cache()
缓存?
分开执行的最佳方法是什么?
答案 0 :(得分:0)
Spark支持两种类型的操作:操作和转换。顾名思义,转换通过转换运算符和(在某些情况下,可选地)提供给转换的函数的组合将数据集转换为新的数据集。另一方面,动作通过具有一些计算的数据集运行,以向驱动程序提供值。
Spark做了两件事使你想要的任务变得有点困难:它将非混洗转换捆绑到称为阶段的执行块中,并且必须通过动作触发调度图中的阶段。
对于您的情况,如果您的输入不是很大,我认为用虚拟动作(例如count()
,collect()
)触发转换是最容易的,因为RDD将是物化。在RDD计算期间,您可以检查Spark UI以收集有关用于创建它的步骤/阶段/作业的任何性能统计信息。
这看起来像是:
val text_file = sc.textFile(filename)
val words = text_file.flatMap(line => line.split(" "))
words.count()
val wordCount = words.map(word => (word, 1))
wordCount.count()
val wordCounts = wordCount.reduceByKey(_ + _)
wordCounts.count()
一些注意事项:
val
reduceByKey()
语法foreachPartition()
的方法可以正常工作,因为它是一个操作,但由于您在分区上的迭代器上操作,因此需要更改函数答案 1 :(得分:0)
您还可以在每次转换后简单地调用RDD.persist()或RDD.cache()。但要确保您定义了正确级别的StorageLevel。