有没有一种方法可以按行拆分RDD?

时间:2019-06-27 12:01:24

标签: java string apache-spark split rdd

我在JavaRDD中有一堆具有20000行的数据。现在,我想保存几个大小完全相同的文件(例如每个文件70行)。

我使用下面的代码进行了尝试,但是由于无法完全分开,因此某些数据集包含69、70或71行。挣扎的是,除了最后一个记录(它可以更少)之外,我需要所有具有相同大小的记录。

帮助表示赞赏!!!预先感谢大家!

myString.repartition(286).saveAsTextFile(outputPath);

2 个答案:

答案 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