一起使用partitionBy和合并

时间:2019-07-19 10:20:25

标签: scala apache-spark apache-spark-sql

我需要基于特定的Partition键将数据写入s3,这可以通过使用write.partitionBy轻松地完成。但是,在这种情况下,我只需要在每个路径中写入一个文件。我正在使用以下代码执行此操作。

    orderFlow.coalesce(1).write.partitionBy("SellerYearMonthWeekKey")
      .mode(SaveMode.Overwrite)
      .format("com.databricks.spark.csv")
      .option("delimiter", ",")
      .option("header", "true")
      .save(outputS3Path + "/")

能否请您以最好的方式帮助我实现这一目标?在上述情况下,我收到了OutOfMemmory错误。

2 个答案:

答案 0 :(得分:1)

如果您要为每个分区输出一个文件,则可以按partitionBy

中使用的同一列对数据集进行重新分区。
   orderFlow.repartition("SellerYearMonthWeekKey")
      .write.partitionBy("SellerYearMonthWeekKey")
      .mode(SaveMode.Overwrite)
      .format("com.databricks.spark.csv")
      .option("delimiter", ",")
      .option("header", "true")
      .save(outputS3Path + "/")

这将花费您洗牌时间,但保证每个分区目录只有一个文件。

答案 1 :(得分:0)

我认为,这可以为您提供帮助-

object Stackoverflow1 {

  def main(args: Array[String]): Unit = {

    val spark = SparkSession.builder().appName("Test").master("local").getOrCreate()

    val rdd = orderFlow.rdd.map(a => (a.getAs[String]("SellerYearMonthWeekKey"),a.toSeq.mkString(",")))

    val outputPath = "<S3_Location>"

      rdd.saveAsHadoopFile(outputPath, classOf[String], classOf[String],
      classOf[CustomMultipleTextOutputFormat])


  }

  class CustomMultipleTextOutputFormat extends MultipleTextOutputFormat[Any, Any] {
    override def generateActualKey(key: Any, value: Any): Any =
      NullWritable.get()

    override def generateFileNameForKeyValue(key: Any, value: Any, name: String): String =
      key.asInstanceOf[String]
  }

}