Spark 3.0 读取 json 个文件比 Spark 2.4 慢得多

Spark 3.0 is much slower to read json files than Spark 2.4

我有大量 json 个文件,Spark 可以在 36 秒内读取这些文件,但 Spark 3.0 需要将近 33 分钟才能读取相同的文件。仔细分析,看起来 Spark 3.0 选择的 DAG 与 Spark 2.0 不同。有谁知道发生了什么事? Spark 3.0有配置问题吗

Spark 2.4

scala> spark.time(spark.read.json("/data/20200528"))
Time taken: 19691 ms
res61: org.apache.spark.sql.DataFrame = [created: bigint, id: string ... 5 more fields]

scala> spark.time(res61.count())
Time taken: 7113 ms
res64: Long = 2605349

Spark 3.0

scala> spark.time(spark.read.json("/data/20200528"))
20/06/29 08:06:53 WARN package: Truncated the string representation of a plan since it was too large. This behavior can be adjusted by setting 'spark.sql.debug.maxToStringFields'.
Time taken: 849652 ms
res0: org.apache.spark.sql.DataFrame = [created: bigint, id: string ... 5 more fields]

scala> spark.time(res0.count())
Time taken: 8201 ms
res2: Long = 2605349

详情如下:

事实证明,Spark 3.0 的默认行为已更改 - 它会尝试推断时间戳,除非指定了模式,这会导致大量文本扫描。我尝试使用 inferTimestamp=false 加载数据,时间确实接近 Spark 2.4 的时间,但 Spark 2.4 仍然比 Spark 3 快 ~3+ 秒(可能在可接受的范围内,但问题是为什么?)。我不知道为什么会更改此行为,但应该以粗体字母通知它。

Spark 2.4

spark.time(spark.read.option("inferTimestamp","false").json("/data/20200528/").count)
Time taken: 29706 ms
res0: Long = 2605349



spark.time(spark.read.option("inferTimestamp","false").option("prefersDecimal","false").json("/data/20200528/").count)
Time taken: 31431 ms
res0: Long = 2605349

Spark 3.0

spark.time(spark.read.option("inferTimestamp","false").json("/data/20200528/").count)
Time taken: 32826 ms
res0: Long = 2605349
 
spark.time(spark.read.option("inferTimestamp","false").option("prefersDecimal","false").json("/data/20200528/").count)
Time taken: 34011 ms
res0: Long = 2605349

注:

  • 确保永远不要将 prefersDecimal 设置为 true,即使 inferTimestamp 是假的,它又需要大量的时间。
  • Spark 3.0 + JDK 11 比 Spark 3.0 + JDK 8 慢将近 6 秒。