火花执行者之间不公平的工作量分配

时间:2018-05-08 04:28:46

标签: apache-spark

我目前正在使用spark来处理文档。我有两台服务器(innov1innov2),我使用yarn作为资源管理器。

第一步是从数据库中收集文件的路径,过滤它们,重新分区并将它们保存在RDD[String]中。但是,我无法公平地分享所有执行者之间的持久性:

persisted RDD memory taken among executors

这导致执行者在此之后做同样的工作:

Work done by each executors(不要关心'死亡'这里,这是另一个问题)

这种情况是随机发生的,有时它会innov1占用所有持久性,然后只有innov1上的执行者工作(但一般来说它往往是innov2) 。现在,每次两个遗嘱执行人都在innov1时,我就会重新开始工作,我祈祷她们在innov2上(这完全是愚蠢的,并打破使用火花的目标)

到目前为止我尝试过的(并且没有用):

  1. 让驱动程序在从数据库加载前60秒睡觉(可能innov1需要更多时间才能唤醒?)
  2. 在我提交作业时提出spark.scheduler.minRegisteredResourcesRatio=1.0(与上述想法相同)
  3. 持续复制x2(来自此link的想法),希望某些块可以在innov1上复制

    注意第3点,有时它是在同一个执行器上持久复制(这有点反直觉),甚至更奇怪,根本没有复制(innov2无法与{{1}进行通信}}?)。

  4. 我愿意接受任何建议,或者链接到我错过的类似问题。

    修改

    我无法将代码放在这里,因为它是我公司产品的一部分。我可以给出一个简化版本:

    innov1

    对于两者都持续存在,所有内容都在val rawHBaseRDD : RDD[(ImmutableBytesWritable, Result)] = sc .newAPIHadoopRDD(...) .map(x => (x._1, x._2)) // from doc of newAPIHadoopRDD .repartition(200) .persist(MEMORY_ONLY) val pathsRDD: RDD[(String, String)] = rawHBaseRDD .mapPartitions { ... extract the key and the path from ImmutableBytesWritable and Result.rawCells() ... } .filter(some cond) .repartition(200) .persist(MEMORY_ONLY) 上。是否有可能是因为数据仅在innov2上?即使是这种情况,我也会认为重新分区有助于在innov2innov1之间共享行,但这并不会发生在这里。

2 个答案:

答案 0 :(得分:0)

您的持久数据集不是很大 - 根据您的屏幕截图,大约100MB。你已经分配了10个核心,内存为20GB,因此100MB很容易融入单个执行器的内存中,这基本上就是发生了什么。

换句话说,您已经分配了比实际需要的资源更多的资源,因此Spark只是随机选择完成作业所需的资源子集。有时,这些资源恰好在一个工人身上,有时在另一个工人身上,有时候它会使用两个工人的资源。

你必须记住,对于Spark来说,如果所有资源都放在一台机器上或者在100台不同的机器上,那就没有区别了 - 只要你不尝试使用更多资源。可用(在这种情况下,你会得到一个OOM)。

答案 1 :(得分:0)

不幸的是(幸运的是?)这个问题今天解决了。我认为它不是火花相关的,因为我没有修改代码直到解决方案。

这可能是由于Ambari完全重启所有服务(即使我不是100%肯定,因为我之前已经尝试过这个),因为这是今天发生的唯一“重大”变化。