我在JavaRDD中有一堆具有20000行的数据。现在,我想保存几个大小完全相同的文件(例如每个文件70行)。
我使用下面的代码进行了尝试,但是由于无法完全分开,因此某些数据集包含69、70或71行。挣扎的是,除了最后一个记录(它可以更少)之外,我需要所有具有相同大小的记录。
帮助表示赞赏!!!预先感谢大家!
myString.repartition(286).saveAsTextFile(outputPath);
答案 0 :(得分:1)
您可以使用filterByRange做类似(伪代码)的事情:
for i = 0; i < javaRDD.size ; i+= 70
val tempRDD = javaRDD.filterByRange(i,i+70).repartition(1)
tempRDD.saveAsTextFile(outputPath + i.toString());
答案 1 :(得分:0)
很不幸,这是Scala的答案,但是可以。
首先定义一个自定义分区程序:
class IndexPartitioner[V](n_per_part: Int, rdd: org.apache.spark.rdd.RDD[_ <: Product2[Long, V]], do_cache: Boolean = true) extends org.apache.spark.Partitioner {
val max = {
if (do_cache) rdd.cache()
rdd.map(_._1).max
}
override def numPartitions: Int = math.ceil(max.toDouble/n_per_part).toInt
override def getPartition(key: Any): Int = key match {
case k:Long => (k/n_per_part).toInt
case _ => (key.hashCode/n_per_part).toInt
}
}
创建随机字符串的RDD并为其建立索引:
val rdd = sc.parallelize(Array.tabulate(1000)(_ => scala.util.Random.alphanumeric.filter(_.isLetter).take(5).mkString))
val rdd_idx = rdd.zipWithIndex.map(_.swap)
创建分区程序并应用它:
val partitioner = new IndexPartitioner(70, rdd_idx)
val rdd_part = rdd_idx.partitionBy(partitioner).values
检查分区大小:
rdd_part
.mapPartitionsWithIndex{case (i,rows) => Iterator((i,rows.size))}
.toDF("partition_number","number_of_records")
.show
/**
+----------------+-----------------+
| 0| 70|
| 1| 70|
| 2| 70|
| 3| 70|
| 4| 70|
| 5| 70|
| 6| 70|
| 7| 70|
| 8| 70|
| 9| 70|
| 10| 70|
| 11| 70|
| 12| 70|
| 13| 70|
| 14| 20|
+----------------+-----------------+
*/
每个分区一个文件:
import sqlContext.implicits._
rdd_part.toDF.write.format("com.databricks.spark.csv").save("/tmp/idx_part_test/")
(“ _ SUCCESS”为+1)
XXX$ ls /tmp/idx_part_test/ | wc -l
16