我有一个Spark SQL,它将我的S3 JSON文件读入DataFrame。
然后我在该DataFrame上运行2个SQL,发现SparkSQL在执行每个SQL之前读取了我的S3 JSON文件两次。
如果DataFrame对象没有被重用,那将会非常昂贵......
感谢任何帮助。
这是我的代码片段:
async-await
答案 0 :(得分:0)
您的JSON文件被读取两次,因为Spark不知道JSON的架构,而SQL需要已知的架构。因此,Spark采取了两次通过的方法:
将所有JSON记录的架构发现为每个JSON记录的架构的联合。
将数据加载到适当配置的数据结构中。
想象一下,你有简单的单行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]