我有一个包含许多未排序行的巨大XML文件:
<row>
<field name="f1">group</field>
<field name="f2">number</field>
<field name="f3">number2</field>
</row>
我希望使用spark将具有不同数字的每个组(f1)提取到一个单独的文件中。
现在我试图先使用map,distinct和collect,然后遍历这个组数组来提取所有组(~50)。使用原始RDD,我过滤与当前组匹配的所有行saveToTextFile。 - 工作,但我很确定这种方式效率最低。
因此我改变了我的xml导入器以返回(f1,(f2,f3))并尝试:
rdd.groupByKey(numPartitions).mapPartitions(part => {
part.map(data => {
val group = data._1
val numbers = data._2
...
}
这是我得到多远,因为现在数字是Iterable [(String,String)],而不是RDD。
我的想法是基本的(伪代码):
rdd.groupByKey(numPartitions).map((group, numbers) => {
numbers.distinct.map(OutputFormatter(_)).
saveAsTextFile(s"$target$group")
}
这里的numPartitions应该与worker的大小相匹配,每个worker有一个组(我也喜欢在这里测试行为,但这是OT)
数字不能在这里成为RDD是正确的,因为groupByKey需要先收集数据吗? 如果不是,我错过了什么?
此操作有一个共同的最佳做法吗?我是spark / hadoop / etc的新手
谢谢。
答案 0 :(得分:0)
我可以想到以下方法,我认为它与您使用过滤的原始解决方案的精神相似,除非我们没有明确地收集到数组。这接近你需要的吗?
def extractGroup(row: Row) = ???
def extractNumbers(row: Row) = ???
val keyed = rdd.keyBy(extractGroup _)
keyed
.map { case (group, row) => group }
.distinct
.foreach { group =>
keyed
.filter { _._1 == group }
.map { case (_, row) => extractNumbers(row) }
.distinct
.map(OutputFormatter(_))
.saveAsTextFile(???)
}