写入和回读时Spark会丢失列

时间:2017-11-16 17:43:55

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

我正在创建一个数据集并将其以镶木地板格式写入目录结构${BasePath}/y=2107/m=11/d=16/中的s3。在我创建当前数据并将其写入s3后,我需要回读最近10天的数据。

我可以做到这两种方式,

第一种方法:将当前日期数据写入s3,读取剩余的9天数据并进行联合,如

dataset.write.mode(SaveMode.Overwrite)
              .format(sourceConfig.format).save(getWriteBasePath(sourceConfig.sourcePath
              , replaceDate))
newDf = spark.read.parquet("path1",...,"path9").union(dataset)

第二种方法:将当前日期数据写入s3,并再次读取所有10天数据。类似的东西:

     dataset.write.mode(SaveMode.Overwrite)
          .format(sourceConfig.format).save(getWriteBasePath(sourceConfig.sourcePath
          , replaceDate))
    newDf = spark.read.parquet("path1",...,"path10")

第一种方法没有任何问题但与第二种方法相比非常慢。但是使用第二种方法,在我将完整的数据重新发送到spark之后,当前日期的一些列将获得空值。我确认当天写的数据是正确的。

我无法弄清楚为什么会这样。我正在创建具有以下属性的spark上下文:

sparkSession.sparkContext.hadoopConfiguration.set("mapreduce.fileoutputcommitter.algorithm.version", "2")
      sparkSession.sparkContext.getConf.set("spark.hadoop.parquet.enable.summary-metadata", "false")
      sparkSession.sparkContext.getConf.set("spark.sql.parquet.mergeSchema", "false")
      sparkSession.sparkContext.getConf.set("spark.sql.parquet.filterPushdown", "true")
      sparkSession.sparkContext.getConf.set("spark.sql.hive.metastorePartitionPruning", "true")

1 个答案:

答案 0 :(得分:0)

我更愿意将当前数据缓存在一个数据框中,并在过去9天内将其读取到另一个数据框中。现在你拥有了内存中的所有数据..你的执行必须更快。在我们写入s3的那一刻(作为一个动作),创建的整个DAG将被刷新,这就是你的第一个方法真正慢的原因。