首页 > 解决方案 > Spark:groupByKey,右侧带有“Iterator”而不是“Iterable”

问题描述

我有一个rdd。我想按一些属性对其进行分组并将每个组保存到一个单独的文件中(并获取结果文件名列表)。最天真的方式:

val rdd : RDD[Long] = ???
val byLastDigit: RDD[(Int, Long)] = rdd.map(n => ((n % 10).toInt, n))
val saved: Array[String] = byLastDigit.groupByKey().map((numbers: (Int, Iterable[Long])) => {  
   //save numbers into a file
   ???
}).collect()

这种方法的缺点是它同时在内存中保存一个键的所有值。所以它在巨大的数据集上效果不佳。

替代方法:

byLastDigit.partitionBy(new HashPartitioner(1000)).mapPartitions((numbers: Iterator[(Int, Long)]) => {
    //assume that all numbers in a partition have the same key
    ???
  }).collect()

由于分区的数量远高于键的数量,每个分区很可能只保存一个键的数字。

它适用于大型数据集。但这很丑陋,而且更容易出错。

能不能做得更好?

标签: scalaapache-spark

解决方案


推荐阅读