Spark SQL read.json读取JSON输入两次

时间:2015-07-19 05:14:46

标签: apache-spark dataframe apache-spark-sql

我有一个Spark SQL,它将我的S3 JSON文件读入DataFrame。

然后我在该DataFrame上运行2个SQL,发现SparkSQL在执行每个SQL之前读取了我的S3 JSON文件两次。

如果DataFrame对象没有被重用,那将会非常昂贵......

感谢任何帮助。

这是我的代码片段:

async-await

1 个答案:

答案 0 :(得分:0)

您的JSON文件被读取两次,因为Spark不知道JSON的架构,而SQL需要已知的架构。因此,Spark采取了两次通过的方法:

  1. 将所有JSON记录的架构发现为每个JSON记录的架构的联合。

  2. 将数据加载到适当配置的数据结构中。

  3. 想象一下,你有简单的单行JSON文件:

    {"category" : "A", "num" : 5}
    

    如果你执行

    sqlContext.read.json(path).saveAsTable("test")

    spark-shell中,您会注意到两次传球。

    第一遍有一个映射阶段,用于收集每个分区发现的模式,reduce阶段将模式组合到所有分区的union模式中。

    对于地图阶段,您会看到以下内容:

    INFO DAGScheduler: Submitting Stage 11 (file:///home/ubuntu/test_data.jsonlines MapPartitionsRDD[28] at textFile at JSONRelation.scala:114), which has no missing parents
    

    对于缩减阶段,您会看到类似的内容:

    INFO SparkContext: Starting job: reduce at JsonRDD.scala:54
    

    之后,当架构已知时,将开始实际加载JSON数据。这只涉及映射阶段,因为一旦发现模式,就不需要在分区处理器之间共享信息。

    您可以看到Spark如何处理日志中的数据列:

    INFO ColumnChunkPageWriteStore: written 56B for [category] BINARY: 1 values, 11B raw, 29B comp, 1 pages, encodings: [PLAIN, RLE, BIT_PACKED]
    INFO ColumnChunkPageWriteStore: written 70B for [num] INT64: 1 values, 14B raw, 29B comp, 1 pages, encodings: [PLAIN, RLE, BIT_PACKED]