Spark 任务随机花费太多时间

问题描述 投票:0回答:1

我已经使用 pyspark 在 databricks 上设置了一个 Spark 集群。首先,我形成一个包含 200 个 s3 路径的列表,每个路径最终都会成为一个数据帧,因此 Spark 中总共有 200 个数据帧并存储到另一个 s3 位置。

形成的每个数据帧都非常小,从 100Kb 到 10Mb 不等。由于这些是非常小的数据帧,我所做的是利用 python ThreadPool 一次发送多个作业,并将 Spark.sql.shuffle.partitions 设置为 1,将并行度设置为 1。

基本上,我实现的是在工作节点的一个核心上仅运行 1 个作业,因为数据帧非常小,并且由于 ThreadPool 创建多个 Spark 作业,并且 ThreadPool 进程计数等于工作核心的数量,因此我实现了并行性。这个想法是数据帧非常小,并且数据帧上的转换处理量不大,我可以通过禁用 Spark 并行性并并行运行 Spark 作业本身(而不是分区)来减少开销。

问题:当这些数据块作业运行时,有时与其他数据帧相比,随机数据帧将花费太多时间来执行。通常 1 个数据帧需要 5 秒到 1 分钟,但随机一个数据帧将需要 1 小时以上。每个数据帧包含来自这 200 个 s3 路径的 1 s3 路径的数据。

Spark Execution Time

集群配置

1x m5.xlarge 驱动器

4x r5.大型工人

(集群配置是根据 Spark 以及该作业执行的其他一些内容来选择的)

我检查过的内容: 1)几乎没有任何没有连接或聚合的转换,并且数据帧不是那么大,因此不存在数据倾斜的可能性。

  1. 将并行度和分区洗牌设置为默认值并不能解决问题。使用所有默认设置也没有帮助。

  2. 当这种情况发生时,它会减慢所有 Spark 步骤中的所有其他任务。

  3. 通过调试,我已经确认这只在执行数据帧内容时发生,没有 s3 检索时间问题,或 s3 写入问题或没有网络延迟。

  4. 推测执行无济于事,因为推测发生在步骤内部而不是跨不同步骤,并且步骤本身花费的时间太长。

  5. 如果我再次运行该作业,相同的 s3 路径不会导致问题,甚至整个 databricks 作业将正常运行,即如果出现问题,databricks 作业将需要 4 小时才能运行,如果问题没有发生,具有相同输入的相同作业将需要 20 分钟才能运行。

  6. 整个执行最终确实完成,但只是需要很多时间。

  7. 我很确定数据不是我调试的问题。

  8. 资源不是问题,有足够的网络、CPU和内存。

amazon-web-services apache-spark pyspark databricks
1个回答
0
投票

任务不会指示分区或数据帧,它可能是重新分区任务。任何数据的重新分区都会导致数据在集群中进行洗牌。

为了提高执行速度,如果您可以控制数据的存储方式,我建议更新源 s3 存储桶以使用不同的分区键重新分区。

注意:以下解决方案假设您有每小时分区的事件流数据

如果您无法控制数据分区,我建议使用 Kinesis Data Firehouse(AWS 托管)或 Kafka(自行管理)使用创建事件从源 s3 读取数据,并将数据缓冲到具有不同分区结构的更大文件大小。然后使用合并输出的输出进行生产,这样在spark集群中更容易处理。

© www.soinside.com 2019 - 2024. All rights reserved.