如何将大型实木复合地板文件拆分为多个实木复合地板并按时间列保存在不同的hadoop路径中

时间:2019-07-03 07:34:49

标签: scala apache-spark rdd parquet large-data

我的这样的口音文件

id,名称,日期

1,a,1980-09-08

2,b,1980-09-08

3,c,2017-09-09

希望这样的输出文件

enter image description here

文件夹19800908包含数据

id,名称,日期

1,a,1980-09-08

2,b,1980-09-08

并且文件夹20170909包含数据

id,名称,日期

3,c,2017-09-09

我知道可以通过密钥date进行分组,但是不知道如何使用此类MultipleTextOutputFormat输出多个实木复合地板文件

我不想foreach循环按键,这会减慢速度并需要大量内存

现在这样的代码

   val input = sqlContext.read.parquet(sourcePath)
      .persist(StorageLevel.DISK_ONLY)

    val keyRows: RDD[(Long, Row)] =
      input.mapPartitions { partition =>
        partition.flatMap { row =>
          val key =  format.format(row.getDate(3)).toLong
          Option((key, row))
        }
      }.persist(StorageLevel.DISK_ONLY)

    val keys = keyRows.keys.distinct().collect()

    for (key <- keys) {
      val rows = keyRows.filter { case (_key, _) => _key == key }.map(_._2)
      val df = sqlContext.createDataFrame(rows, input.schema)
      val path = s"${outputPrefix}/$key"
      HDFSUtils.deleteIfExist(path)
      df.write.parquet(path)
    }

如果我使用MultipleTextOutputFormat,则输出如下,我不需要

enter image description here

    keyRows.groupByKey()
      .saveAsHadoopFile(conf.getOutputPrefixDirectory, classOf[String], classOf[String],
        classOf[SimpleMultipleTextOutputFormat[_, _]])
public class SimpleMultipleTextOutputFormat<A, B> extends MultipleTextOutputFormat<A, B> {

    @Override
    protected String generateFileNameForKeyValue(A key, B value, String name) {
//        return super.generateFileNameForKeyValue(key, value, name);
        return key.toString();
    }
}

2 个答案:

答案 0 :(得分:1)

可以使用带有分区列的文字:

df.write.partitionBy("dateString").parquet("/path/to/file").

差异-文件夹名称将类似于“ dateString = 2017-09-09”,并且必须在保存之前创建新的字符串列“ dateString”。

答案 1 :(得分:0)

此帖子spark partition data writing by timestamp

    input
      .withColumn("_key", date_format(col(partitionField), format.toPattern))
      .write
      .partitionBy("_key")
      .parquet(conf.getOutputPrefixDirectory)

enter image description here

但是如何删除文件夹名称'_ke ='