我目前正在使用spark
来处理文档。我有两台服务器(innov1
和innov2
),我使用yarn
作为资源管理器。
第一步是从数据库中收集文件的路径,过滤它们,重新分区并将它们保存在RDD[String]
中。但是,我无法公平地分享所有执行者之间的持久性:
persisted RDD memory taken among executors
这导致执行者不在此之后做同样的工作:
Work done by each executors(不要关心'死亡'这里,这是另一个问题)
这种情况是随机发生的,有时它会innov1
占用所有持久性,然后只有innov1
上的执行者工作(但一般来说它往往是innov2
) 。现在,每次两个遗嘱执行人都在innov1
时,我就会重新开始工作,我祈祷她们在innov2
上(这完全是愚蠢的,并打破使用火花的目标)
到目前为止我尝试过的(并且没有用):
innov1
需要更多时间才能唤醒?)spark.scheduler.minRegisteredResourcesRatio=1.0
(与上述想法相同)持续复制x2(来自此link的想法),希望某些块可以在innov1上复制
注意第3点,有时它是在同一个执行器上持久复制(这有点反直觉),甚至更奇怪,根本没有复制(innov2
无法与{{1}进行通信}}?)。
我愿意接受任何建议,或者链接到我错过的类似问题。
修改
我无法将代码放在这里,因为它是我公司产品的一部分。我可以给出一个简化版本:
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
上?即使是这种情况,我也会认为重新分区有助于在innov2
和innov1
之间共享行,但这并不会发生在这里。
答案 0 :(得分:0)
您的持久数据集不是很大 - 根据您的屏幕截图,大约100MB。你已经分配了10个核心,内存为20GB,因此100MB很容易融入单个执行器的内存中,这基本上就是发生了什么。
换句话说,您已经分配了比实际需要的资源更多的资源,因此Spark只是随机选择完成作业所需的资源子集。有时,这些资源恰好在一个工人身上,有时在另一个工人身上,有时候它会使用两个工人的资源。
你必须记住,对于Spark来说,如果所有资源都放在一台机器上或者在100台不同的机器上,那就没有区别了 - 只要你不尝试使用更多资源。可用(在这种情况下,你会得到一个OOM)。
答案 1 :(得分:0)
不幸的是(幸运的是?)这个问题今天解决了。我认为它不是火花相关的,因为我没有修改代码直到解决方案。
这可能是由于Ambari完全重启所有服务(即使我不是100%肯定,因为我之前已经尝试过这个),因为这是今天发生的唯一“重大”变化。