当更多可用时,Spark只使用一台工作机

时间:2017-10-20 18:08:53

标签: python apache-spark pyspark

我试图通过Spark并行化机器学习预测任务。我之前已经成功地使用过Spark多次其他任务,之前并没有遇到并行化问题。

在此特定任务中,我的群集有4名工作人员。我在一个有4个分区的RDD上调用mapPartitions。 map函数从磁盘加载模型(bootstrap脚本分发执行此操作所需的所有内容;我已经验证它存在于每个从属计算机上)并对RDD分区中的数据点执行预测。

代码运行,但只使用一个执行程序。其他执行者的日志说" Shutdown hook称为"。在不同的代码运行中,它使用不同的机器,但一次只使用一台。

如何让Spark一次使用多台机器?

我通过Zeppelin笔记本在Amazon EMR上使用PySpark。代码片段如下。

%spark.pyspark

sc.addPyFile("/home/hadoop/MyClassifier.py")
sc.addPyFile("/home/hadoop/ModelLoader.py")

from ModelLoader import ModelLoader
from MyClassifier import MyClassifier

def load_models():
    models_path = '/home/hadoop/models'
    model_loader = ModelLoader(models_path)

    models = model_loader.load_models()
    return models

def process_file(file_contents, models):
    filename = file_contents[0]
    filetext = file_contents[1]
    pred = MyClassifier.predict(filetext, models)
    return (filename, pred)

def process_partition(file_list):
    models = load_models()
    for file_contents in file_list:
        pred = process_file(file_contents, models)
        yield pred


all_contents = sc.wholeTextFiles("s3://some-path", 4)
processed_pages = all_contents.mapPartitions(process_partition)
processedDF = processed_pages.toDF(["filename", "pred"])
processedDF.write.json("s3://some-other-path", mode='overwrite')

预期有四个任务,但它们都在同一个执行器上运行!

我正在运行集群,并且可以在资源管理器中提供可用的日志。我只是不知道在哪里看。

2 个答案:

答案 0 :(得分:4)

这里要提两点(不确定它们是否能解决你的问题):

  1. wholeTextFiles使用扩展WholeTextFileInputFormat的{​​{1}},并且由于CombineFileInputFormat,它会尝试将小组文件组合到一个分区中。因此,如果您将分区数设置为2,例如,您可能会获得两个分区,但不能保证,这取决于您正在阅读的文件的大小。
  2. CombineFileInputFormat的输出是一个RDD,其中包含每个记录中的整个文件(并且每个记录/文件都不能被拆分,因此它将以单个分区/工作者的身份结束)。因此,如果您只读取一个文件,则最终将完整文件放在一个分区中,尽管您在示例中将分区设置为4。

答案 1 :(得分:2)

该进程具有您指定的分区数,但它是以序列化方式进行的。

<强>执行人

该过程可能会启动默认的执行程序数。这可以在纱线资源管理器中看到。在您的情况下,所有处理都由一个执行者完成。如果遗嘱执行人拥有多个核心,那么这将使这项工作变得简单。在emr中,您可以执行此更改,以便为执行程序提供多于1个核心。

在我们的案例中特别发生的是,数据很小,因此所有数据都在一个执行器中读取(即使用一个节点)。如果没有以下属性,则执行程序仅使用单核。因此,所有任务都是序列化的。

设置属性

sudo  vi /etc/hadoop/conf/capacity-scheduler.xml

如图所示设置以下属性

"yarn.scheduler.capacity.resource-calculator": "org.apache.hadoop.yarn.util.resource.DominantResourceCalcul‌​ator"

为了使此属性适用,您必须重新启动纱线

 sudo  hadoop-yarn-resourcemanager stop

重新启动纱线

 sudo  hadoop-yarn-resourcemanager start 

提交作业后,请参阅纱线和spark-ui

在Yarn中,您将看到更多执行者核心