6

pyspark使用默认设置在 8 节点 Google dataproc 集群上运行。启动几秒钟后,我看到 30 个执行程序核心正在运行(如预期的那样):

    >>> sc.defaultParallelism
    30

一分钟后:

    >>> sc.defaultParallelism
    2

从那时起,所有操作仅在 2 个核心上运行:

    >>> rng = sc.parallelize(范围(1,1000000))
    >>> rng.cache()
    >>> rng.count()
    >>> rng.getNumPartitions()
    2

如果我rng.cache()在核心仍然连接的情况下运行,它们会保持连接并且作业会被分配。

检查监控应用程序(主节点上的端口 4040)显示执行程序已被删除:

Executor 1
Removed at 2016/02/25 16:20:14
Reason: Container container_1456414665542_0006_01_000002 exited from explicit termination request." 

是否有一些设置可以在没有变通方法的情况下保持核心连接?

4

1 回答 1

11

在大多数情况下,您所看到的实际上只是 YARN 上的 Spark 配置方式与 spark 独立方式的差异。目前,YARN 报告的“VCores Used”实际上并不能正确对应于真正的容器预留核心,而容器实际上只是基于内存预留。

总的来说,这里有几件事在起作用:

动态分配导致 Spark 将空闲的执行程序放回 YARN,不幸的是,目前 spark 打印出垃圾邮件但无害的“丢失的执行程序”消息。这是 YARN 上 spark 的经典问题,其中 spark 最初会瘫痪它运行的集群,因为它会获取它认为需要的最大数量的容器,然后永远不会放弃它们。

使用动态分配,当你开始一个长时间的工作时,spark 会快速分配新的容器(通过指数增长,可以在几分钟内快速填满一个完整的 YARN 集群),当空闲时,放弃具有相同增长的执行程序-down 间隔大约 60 秒(如果空闲 60 秒,则放弃一些执行程序)。

如果要禁用动态分配,可以运行:

spark-shell --conf spark.dynamicAllocation.enabled=false

gcloud dataproc jobs submit spark --properties spark.dynamicAllocation.enabled=false --cluster <your-cluster> foo.jar

或者,如果您指定固定数量的执行器,它也应该自动禁用动态分配:

spark-shell --conf spark.executor.instances=123

gcloud dataproc jobs submit spark --properties spark.executor.instances=123 --cluster <your-cluster> foo.jar
于 2016-02-26T12:04:15.543 回答