【问题标题】:Spark DataFrame limit function takes too much time to showSpark DataFrame 限制函数需要太多时间才能显示
【发布时间】:2019-07-04 00:58:22
【问题描述】:
import pyspark
from pyspark.sql import SparkSession
from pyspark.conf import SparkConf
import findspark
from pyspark.sql.functions import countDistinct
spark = SparkSession.builder \
.master("local[*]") \
.appName("usres mobile related information analysis") \
.config("spark.submit.deployMode", "client") \
.config("spark.executor.memory","3g") \
.config("spark.driver.maxResultSize", "1g") \
.config("spark.executor.pyspark.memory","3g") \
.enableHiveSupport() \
.getOrCreate()

handset_info =ora_tmp.select('some_value','some_value','some_value','some_value','some_value','some_value','some_value')

我用 3gb 执行内存和 3gb 执行 pyspark 内存配置 spark。我的数据库有超过 7000 万行。显示我打电话给

 handset_info.show()

它在 2-5 秒之间显示前 20 行的方法。但是当我尝试运行以下代码时

mobile_info_df = handset_info.limit(30)
mobile_info_df.show()

显示前 30 行需要花费太多时间(3-4 小时)。花那么多时间合乎逻辑吗?我的配置有问题吗。 我的笔记本电脑的配置是-

  • Core i7(4 核)笔记本电脑,8GB 内存

【问题讨论】:

    标签: python-3.x pyspark bigdata data-science


    【解决方案1】:

    您的配置很好。这种巨大的持续时间差异是由底层实现引起的。不同之处在于 limit() 在创建一个包含 30 行的数据帧之前读取了所有 7000 万行。相比之下,Show() 只获取现有数据帧的前 20 行,因此只需读取这 20 行。 如果您只想显示 30 行而不是 20 行,可以调用 show() 方法,参数为 30:

    df.show(30, truncate=False)
    

    【讨论】:

    • 你知道为什么limit() 会这样吗?这让我觉得相当浪费......
    • 你说的好像不太对,见:github.com/apache/spark/pull/15070
    • @minhle_r7 我看不出这个 PR 与 OP 的场景有什么关系。 OP 创建两个数据帧mobile_info_dfhandset_info。第一个应该只包含 30 行,另一个不限制。这意味着需要读取整个数据(show 触发读取)。我现在无法测试它,因为我目前没有spark环境,但是mobile_info_df = handset_info.limit(30)handset_info = handset_info.limit(30)可能会导致不同的执行计划。 1/2
    • @minhle_r7 后者的性能会比show 好得多(我可能说过!我还没有测试过。)。也许您可以自己检查并编辑我的答案以改进它。 2/2
    • 在下面查看我的答案
    【解决方案2】:

    正如您已经体验过的,limit() 处理大数据的性能很差。想为其他有此问题的人分享解决方法。 如果限制计数不必精确,请使用 sort() 或 orderBy() 对列进行排序,并使用 filter() 获取前 k% 的行。

    【讨论】:

    • 您能否提供一个示例来说明如何使用sort() + filter() 来获取前10% 的行?
    • @EasonL 所以这不会让你得到 x% 因为谁知道有多少行满足 filter() 条件,但你会做这样的事情:df.sort("score").filter("score > 0.9") 如果你对你的数据分布......你可以接近你想要的 X% 或行数......
    【解决方案3】:

    Spark 将您传递给 limit() 的参数复制到每个分区,因此,在您的情况下,它会尝试读取每个分区的 30 行。我猜你碰巧有大量的分区(无论如何这都不好)。试试df.coalesce(1).limit(30).show(),它的运行速度应该和df.show()一样快。

    【讨论】:

    • 我不确定。 Spark通常用于大数据,可以轻松拥有1000个分区进行并行化。如果将其限制为单个分区(这也意味着单核),它就没有那么有用了。在这种情况下,您可能只使用 pandas。
    • 但是,.coalesce(1).limit(30) 确实工作得更快!谢谢!
    • coalesce()调用只影响后续调用的规划;这并不意味着您的数据会立即组合成一个大块;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多