假设我们有以下Scala计划:
val inputRDD = sc.textFile("log.txt")
inputRDD.persist()
val errorsRDD = inputRDD.filter(lambda x: "error" in x)
val warningsRDD = inputRDD.filter(lambda x: "warning" in x)
println("Errors: " + errorsRDD.count() + ", Warnings: " + warningsRDD.count())
我们创建一个简单的RDD,持久化它,在RDD上执行两次转换,最后有一个使用RDD的动作。
当调用print时,执行转换,每个转换当然是并行的,具体取决于集群管理。
我的主要问题是:两个动作和转换是并行执行还是顺序执行?或errorsRDD.count()
首先执行,然后依次warningsRDD.count()
执行?
我也想知道在这个例子中使用persist是否有任何意义。
答案 0 :(得分:2)
所有标准RDD方法都是阻塞的(AsyncRDDActions
除外),因此将按顺序评估操作。可以使用非阻塞提交(线程,Futures
)同时执行多个操作,并为每个操作配置正确的应用程序调度程序或明确限制的资源。
关于cache
,如果不了解背景,就无法回答。根据群集配置,存储和数据位置,再次从磁盘加载数据可能更便宜,尤其是在资源有限的情况下,后续操作可能会触发缓存清理。
答案 1 :(得分:1)
首先执行errorsRDD.count()
然后warningsRDD.count()
。
这里使用persist的意义在于执行第一个计数时,inputRDD将在内存中。
第二个计算,火花不需要重新阅读"整个"再次存储文件的内容,因此这个计数的执行时间比第一个快得多。