我正在尝试找到一种有效的方法,将在任务中创建的集合写入作业的输出文件。例如,如果我们使用foreach
迭代RDD,我们可以在以下代码片段中创建对于执行者({1}}本地的数据结构。我的问题是如何序列化ListBuffer arr
并将其写入文件?
(1)我应该使用arr
api还是Spark FileWriter
会起作用?
(2)使用一个优于另一个的优点是什么
(3)有没有更好的方法来实现同样的目标。
PS:我使用saveAsTextFile
而不是foreach
的原因是因为我可能无法转换所有RDD行,并且我希望避免在输出中获取Null值。
map
谢谢, Devj
答案 0 :(得分:3)
你不应该使用驱动程序的变量,但是累加器 - 以及关于它们的文章,代码示例here和here,this问题也许有用 - 简化了自定义select distinct
columnA + [Column_in_question]
from [dbo].[Tabled_in_question]
编写您自己的累加器,可以添加AccumulatorParam
或使用内置CollectionAccumulator
。这是来自Spark 2的新版累加器AccumulatorV2的实现
其他方式是使用Spark内置过滤器和地图功能 - 感谢@ImDarrenG建议flatMap,但我认为过滤器和地图会更容易:
(String, String)
答案 1 :(得分:2)
Spark API为您节省了一些文件处理代码,但基本上可以实现相同的目的。
例外情况是,如果您不使用HDFS,并且不希望对输出文件进行分区(遍布执行程序文件系统)。在这种情况下,您需要将数据收集到驱动程序并使用FileWriter写入单个文件或文件,以及您实现的方式取决于您拥有的数据量。如果你有比驱动程序有更多内存的数据,你将需要以不同的方式处理它。
正如另一个答案中所提到的,您在驱动程序中创建一个数组,同时添加执行程序中的项目,这些项目在集群环境中无效。这样的事情可能是映射数据和处理空值的更好方法:
val outputRDD = dataSorted.flatMap {
case (e, r) => {
if(e.id > 1000) {
Some(("a", "b"))
} else {
None
}
}
}
// save outputRDD to file/s here using the approapriate method...