同时调度许多Spark作业时出现死锁


17

通过spark FIFO调度程序使用在YARN集群模式下运行的spark 2.4.4。

我正在使用线程数可变的线程池执行程序来提交多个spark数据帧操作(即,将数据写入S3)。如果我有约10个线程,则可以正常工作,但如果使用数百个线程,则似乎出现了死锁,根据Spark UI没有安排任何作业。

哪些因素控制可以同时调度多少个作业?驱动程序资源(例如内存/内核)?其他一些Spark配置设置?

编辑:

这是我的代码的简要提要

ExecutorService pool = Executors.newFixedThreadPool(nThreads);
ExecutorCompletionService<Void> ecs = new ExecutorCompletionService<>(pool);

Dataset<Row> aHugeDf = spark.read.json(hundredsOfPaths);

List<Future<Void>> futures = listOfSeveralHundredThings
  .stream()
  .map(aThing -> ecs.submit(() -> {
    df
      .filter(col("some_column").equalTo(aThing))
      .write()
      .format("org.apache.hudi")
      .options(writeOptions)
      .save(outputPathFor(aThing));
    return null;
  }))
  .collect(Collectors.toList());

IntStream.range(0, futures.size()).forEach(i -> ecs.poll(30, TimeUnit.MINUTES));
exec.shutdownNow();

在某个时候,随着nThreads增加,spark似乎不再在安排任何作业,如以下所示:

  • ecs.poll(...) 最终超时
  • Spark UI作业选项卡显示无活动作业
  • Spark UI执行程序选项卡不显示任何执行程序的活动任务
  • Spark UI SQL选项卡显示nThreads没有运行作业ID的运行查询

我的执行环境是

  • AWS EMR 5.28.1
  • 星火2.4.4
  • 主节点= m5.4xlarge
  • 核心节点= 3x rd5.24xlarge
  • spark.driver.cores=24
  • spark.driver.memory=32g
  • spark.executor.memory=21g
  • spark.scheduler.mode=FIFO


是否有专门的章节对此进行讨论?在过去的几天中,我已经多次阅读这些文档,但没有找到我想要的答案。
斯科特

2
您能否显示用于通过线程池执行程序提交Spark作业的代码?在提交Spark作业之前,似乎发生了死锁。
Salim

1
您可以发布代码吗?请提供有关您的环境的详细信息:CPU,RAM;还有如何创建线程:同时还是以10个为一组的方式创建?
萨希德

抱歉,您的工作没有计划吗?它们没有出现在Spark UI上,或者出现在作业列表中,但是任务没有执行?无论哪种方式,如果您怀疑死锁,请运行jstack -l以获取带有锁定信息的线程转储。
Daniel Darabos

Answers:


0

如果可能,将作业的输出写入AWS Elastic MapReduce hdfs(以利用本地hdfs的几乎瞬时重命名和更好的文件IO)并添加dstcp步骤以将文件移至S3,从而省去了处理试图成为文件系统的对象存储的内部结构。同样,写入本地hdfs将使您能够推测以控制失控任务,而不会陷入与DirectOutputCommiter相关的死锁陷阱。

如果必须使用S3作为输出目录,请确保设置了以下Spark配置

spark.hadoop.mapreduce.fileoutputcommitter.algorithm.version 2
spark.speculation false

注意:由于数据丢失的可能性,DirectParquetOutputCommitter已从Spark 2.0中删除。不幸的是,直到我们从S3a提高了一致性之前,我们都必须使用变通办法。Hadoop 2.8改善了一切

避免按字典顺序使用键名。一种可能是使用散列/随机前缀或反向日期时间来解决。诀窍是按层次命名您的密钥,将最常过滤的内容放在密钥的左侧。决不会由于DNS问题而在存储桶名称中添加下划线。

fs.s3a.fast.upload upload将单个文件的一部分并行启用到Amazon S3

请参阅这些文章以获取更多详细信息-

在写入s3时在Spark 2.1.0中设置spark.speculation

https://medium.com/@subhojit20_27731/apache-spark-and-amazon-s3-gotchas-and-best-practices-a767242f3d98



0

IMO,您可能会错误地解决此问题。除非可以保证每个作业的任务数量很少,否则一次并行处理100个作业可能不会获得很大的性能提升。假设您使用的默认并行度为200,即仅1.5个作业,则群集一次只能支持300个任务。我建议您重写代码,以将最大并发查询数限制为10。由于这个原因,与更传统的RDS系统相比,大多数OLTP数据处理系统有意地具有相当低的并行查询级别。

  1. Apache Hudi的默认并行度为数百FYI。
  2. 您为什么不仅基于过滤器列进行分区?
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.