我刚开始学习Spark和Scala。
根据我的理解,使用collect
是不好的做法,因为它会将整个数据收集到内存中,并且使用for
也是不好的做法,因为块内的代码不会同时执行多个节点。
现在,我有一个从1到10的数字列表:
List(1,2,3,4,5,6,7,8,9,10)
并且对于每个值,我需要使用此值生成RDD
。
在这种情况下,我该如何生成RDD
?
通过
sc.parallelize(List(1,2,3,4,5,6,7,8,9,10)).map(number => generate_rdd(number))
我收到错误,因为无法在另一个RDD中生成RDD。
此问题的最佳解决方法是什么?
答案 0 :(得分:2)
假设generate_rdd
定义为def generate_rdd(n: Int): RDD[Something]
,您需要的是flatMap
而不是map
。
sc.parallelize(List(1,2,3,4,5,6,7,8,9,10)).flatMap(number => generate_rdd(number))
这将给出一个RDD,它是为1到10之间的数字创建的所有RDD的串联。
答案 1 :(得分:1)
假设您想要创建的RDD数量较少,因此并行化本身不需要由RDD完成,我们可以使用Scala的并行集合。例如,我尝试使用以下代码同时计算大约40个HDFS文件中的行数[忽略分隔符的设置。对于换行符分隔的文本,这可能已被sc.textFile
]取代:
val conf = new Configuration(sc.hadoopConfiguration)
conf.set("textinputformat.record.delimiter", "~^~")
val parSeq = List("path of file1.xsv","path of file2.xsv",...).par
parSeq.map(x => {
val rdd = sc.newAPIHadoopFile(x, classOf[TextInputFormat], classOf[LongWritable], classOf[Text], conf)
println(rdd.count())
})
以下是Spark UI中输出的一部分。如图所示,大多数RDD计数操作同时开始。