【发布时间】:2019-02-11 20:45:45
【问题描述】:
我正在尝试做一些非常简单的事情,但我遇到了一些非常愚蠢的挣扎。我认为这一定与对 spark 在做什么的根本误解有关。我将不胜感激任何帮助或解释。
我有一个非常大的(~3 TB,~300MM 行,25k 个分区)表,在 s3 中保存为 parquet,我想给某人一个小样本作为单个 parquet 文件。不幸的是,这需要很长时间才能完成,我不明白为什么。我尝试了以下方法:
tiny = spark.sql("SELECT * FROM db.big_table LIMIT 500")
tiny.coalesce(1).write.saveAsTable("db.tiny_table")
然后当它不起作用时,我尝试了这个,我认为应该是相同的,但我不确定。 (为了调试,我添加了print。)
tiny = spark.table("db.big_table").limit(500).coalesce(1)
print(tiny.count())
print(tiny.show(10))
tiny.write.saveAsTable("db.tiny_table")
当我观看 Yarn UI 时,两个打印语句和write 都使用 25k 映射器。 count 用了 3 分钟,show 用了 25 分钟,write 用了大约 40 分钟,尽管它最终确实写了我正在寻找的单个文件表。
在我看来,第一行应该取前 500 行并将它们合并到一个分区,然后其他行应该发生得非常快(在单个映射器/减速器上)。谁能看到我在这里做错了什么?有人告诉我,也许我应该使用sample 而不是limit,但据我所知limit 应该更快。对吗?
提前感谢您的任何想法!
【问题讨论】:
-
你能签入计划“LIMIT 500”被推送到表吗?
-
@Karthick
spark.sql和数据帧(例如.limit(500))都是由同一个引擎优化的,所以应该不是问题吗? -
我不关心 spark.sql 和同一引擎优化的数据帧,没有理由读取花费太长时间才能获得 500 条记录。 spark ui 运行时的计划中的快速点将获得一些方向(应用限制,只有 500 条记录是从表中流出的内容,以及上面的 numpartition 是什么 - 我期望它为“1”的并行度参数)是什么我的想法。
标签: apache-spark pyspark pyspark-sql