我使用默认设置在8节点Google dataproc群集上运行pyspark
。
启动后几秒钟我看到30个执行器核心正在运行(正如预期的那样):
>>> sc.defaultParallelism 30
一分钟后:
>>> sc.defaultParallelism 2
从那时起,所有操作仅在2个核心上运行:
>>> rng = sc.parallelize(range(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."
是否有一些设置可以在没有解决方法的情况下保持核心连接?
答案 0 :(得分:11)
在大多数情况下,您所看到的实际上只是可以配置Spark on YARN与spark独立的差异。目前,YARN报告的“使用过的VCores”实际上并没有正确对应核心的真实容器预留,而容器实际上只是基于内存预留。
总的来说,这里有一些事情可以发挥作用:动态分配导致Spark将空闲执行程序放回YARN,不幸的是,此刻spark打印出垃圾邮件但无害的“丢失执行程序”消息。这是YARN上经典的火花问题,火花最初瘫痪了它所运行的星团,因为它会抓住它认为需要的最大数量的容器,然后永远不会放弃它们。
通过动态分配,当你开始一个长时间的工作时,火花会快速分配新的容器(有一些像指数式的提升,可以在几分钟内快速填满一个完整的YARN集群),并且当空闲时,放弃执行者以大约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