我有多个spark提交作业,需要作为AWS EMR集群上的Step提交,我的步骤的数据输入对于所有步骤都是相同的,这些步骤当前位于S3存储桶中,输出也在s3上,并且所有步骤都需要并行执行。
目前AWS EMR不支持spark-submit的并行执行,但有一种方法是通过将EMR的YARN调度程序更改为FAIR Scheduler,但这种方法的问题是我们需要为执行程序手动定义Cores / Memory是一个开销。
在AWS EMR中搜索处理此方案的最佳方法,任何建议????
谢谢, -Jack
答案 0 :(得分:7)
目前,AWS EMR不支持并行执行spark-submit
实际上它受到支持但有点棘手。这有两个主要问题,每个Spark作业使用的执行程序数和主节点上驱动程序进程的内存量。
如果你事先知道同时执行spark-submits的最大数量(N),你可以使用--driver-memory, - num-executors, - executor-cores和--executor-memory参数来确保每个作业只占用可用资源的1 / N(如果可以等到提交的作业完成,则可以更多)。如果在实践中很少发生这种并行执行,那么效率非常低。
更好的方法是使用动态分配: https://spark.apache.org/docs/latest/configuration.html#dynamic-allocation
可以使用的参数很少,但是当没有其他作业正在运行时,它将允许单个作业利用几乎所有可用资源(如果maxExecutors是spark.dynamicAllocation.maxExecutors是给定集合的最大可用执行程序数)参数)并且如果多个正在运行,则回退到在作业之间均匀地共享执行者。虽然正在运行的任务不会中断,但这种重新平衡不会立即发生。此外,为此,所有spark-submit调用都必须使用动态分配。如果其中一个spark-submit调用不使用动态分配,它仍然可以获取所有资源并使剩余的Spark作业挨饿。
以下是动态分配参数的示例:
spark-submit \
--deploy-mode client \
--master yarn \
--conf spark.dynamicAllocation.enabled=true \
--conf spark.shuffle.service.enabled=true \
--conf spark.dynamicAllocation.executorIdleTimeout=60s \
--conf spark.dynamicAllocation.cachedExecutorIdleTimeout=60s \
--conf spark.dynamicAllocation.minExecutors=1 \
--conf spark.dynamicAllocation.maxExecutors=4 \
--conf spark.dynamicAllocation.initialExecutors=1 \
<other Spark options>
对于具有8个节点的群集:
FAIR调度也可以工作,它允许比动态分配更好地利用集群资源(因为它不会等到executorIdleTimeout或cachedExecutorIdleTimeout到期)但它只适用于同一Spark App中不同线程发起的多个并行作业(在同一个SparkContext中):https://spark.apache.org/docs/latest/job-scheduling.html。
启用此功能可能需要进行一些应用程序架构更改。例如。该应用程序可以从队列中读取处理请求或公开Web服务以接收它们。