Python 为什么PySpark任务花费了太多时间?

Python 为什么PySpark任务花费了太多时间?,python,apache-spark,pyspark,bigdata,user-defined-functions,Python,Apache Spark,Pyspark,Bigdata,User Defined Functions,我正在运行一个Pyspark进程,它可以正常工作。该过程的第一步是将特定的UDF应用于数据帧。这就是功能: import html2text class Udfs(object): def __init__(self): self.h2t = html2text.HTML2Text() self.h2t.ignore_links = True self.h2t.ignore_images = True def extract_t

我正在运行一个Pyspark进程,它可以正常工作。该过程的第一步是将特定的UDF应用于数据帧。这就是功能:

import html2text

class Udfs(object):
    def __init__(self):
        self.h2t = html2text.HTML2Text()
        self.h2t.ignore_links = True
        self.h2t.ignore_images = True

    def extract_text(self, raw_text):
        try:
            texto = self.h2t.handle(raw_text)
        except:
            texto = "PARSE HTML ERROR"
        return texto
以下是我如何应用UDF:

import pyspark.sql.functions as f
import pyspark.sql.types as t
from udfs import Udfs

udfs = Udfs()
extract_text_udf = f.udf(udfs.extract_text, t.StringType())
df = df.withColumn("texto", extract_text_udf("html_raw"))
它处理大约2900万行和300GB。问题是有些任务需要花费太多的时间来处理。任务的平均时间为:

其他任务已完成,持续时间超过1小时

但有些任务需要花费太多时间处理:

该进程在AWS中运行,具有100个节点的集群中的EMR,每个节点具有32gb的RAM和4个CPU。此外,还启用了火花投机

这些任务的问题在哪里? 这是UDF的问题吗?
这是一个线程问题?

我的直觉是您使用了太多的分区。我会第一次尝试大幅减少他们的数量。你会发现这个话题很有趣

如果分区是平衡的,则按分区平均有
2900万/80k个分区=362
个观察值。我想这还不够。你花了很多时间安排任务,而不是执行任务

如果没有平衡分区,情况会变得更糟(请参阅)。这通常会造成瓶颈,这在您的情况下似乎会发生。有几种选择:

  • 您可以
    合并
    您的数据到数量较少的分区。这比使用
    重新分区
    要好,因为它避免了完全的混乱
  • repartitionByRange
    如果您希望基于某些列分割数据。您将不会像使用
    coalesce
    repartition
    那样拥有平衡的分区,但如果您需要使用这些分割列的操作,则使用后者会很有用
您可以使用
spark.sql.shuffle.partitions
spark.default.parallelism
更改有关分区的默认值


根据我的经验,这是一个猜测。找到足够数量的分区很难,但值得。请告诉我这是否有帮助,或者您是否仍然遇到瓶颈。

我在第一个数据帧中找到了使用repartitionByRange的解决方案。使用正确的id和分区数进行签名可以平衡每个分区中的行数。

>您的分区数是多少?您是否尝试重新分区或更改数据帧的分区数?可能您的分区不平衡:您在调用udf之前是否执行了可能导致分区不平衡的操作?不平衡是什么意思?如何平衡数据帧?在运行数据帧之前我已经用80000个分区进行了重新分区。我说的不平衡是指一些分区,我指的是2900万行在分区之间没有统一划分。你可以找到一些元素。我认为这是多分区的方式。如果我是你,我会尝试使用更少的分区。所以可能是分区不平衡的问题。我的谁能帮你?