ChatGPT解决这个技术问题 Extra ChatGPT

Spark Standalone集群中的workers、executors、cores是什么?

我阅读了 Cluster Mode Overview,但仍然无法理解 Spark Standalone 集群中的不同进程和并行性。

worker 是否是 JVM 进程?我运行 bin\start-slave.sh 并发现它产生了工作程序,它实际上是一个 JVM。

根据上面的链接,执行程序是为运行任务的工作节点上的应用程序启动的进程。执行器也是 JVM。

这些是我的问题:

执行者是每个应用程序。那么工人的作用是什么?它是否与执行者协调并将结果传回给驱动程序?还是司机直接与执行人对话?如果是这样,那么工人的目的是什么?如何控制应用程序的执行者数量?可以使任务在执行器内部并行运行吗?如果是这样,如何配置执行器的线程数?工人、执行者和执行者核心(--total-executor-cores)之间的关系是什么?每个节点有更多的工作人员意味着什么?

更新

让我们举个例子来更好地理解。

示例 1:具有 5 个工作节点(每个节点有 8 个核心)的独立集群当我使用默认设置启动应用程序时。

示例 2 与示例 1 相同的集群配置,但我使用以下设置运行应用程序 --executor-cores 10 --total-executor-cores 10。

示例 3 与示例 1 相同的集群配置,但我使用以下设置运行应用程序 --executor-cores 10 --total-executor-cores 50。

示例 4 与示例 1 相同的集群配置,但我使用以下设置运行应用程序 --executor-cores 50 --total-executor-cores 50。

示例 5 与示例 1 相同的集群配置,但我使用以下设置运行应用程序 --executor-cores 50 --total-executor-cores 10。

在每个示例中,有多少执行者?每个执行器有多少个线程?几核?每个申请的执行人数量是如何决定的?它总是与工人的数量相同吗?


C
Community

https://i.stack.imgur.com/cwrMN.png

Spark 使用主/从架构。如图所示,它有一个中央协调器(Driver),它与许多分布式工作人员(执行者)进行通信。驱动程序和每个执行程序在它们自己的 Java 进程中运行。

司机

驱动程序是 main 方法运行的进程。首先它将用户程序转换为任务,然后将任务安排在执行程序上。

执行者

执行器是工作节点的进程,负责在给定的 Spark 作业中运行各个任务。它们在 Spark 应用程序开始时启动,通常在应用程序的整个生命周期内运行。一旦他们运行了任务,他们就会将结果发送给驱动程序。它们还为用户程序通过块管理器缓存的 RDD 提供内存存储。

应用程序执行流程

考虑到这一点,当您使用 spark-submit 向集群提交应用程序时,内部会发生以下情况:

一个独立的应用程序启动并实例化一个 SparkContext 实例(只有在那时你才能将应用程序称为驱动程序)。驱动程序向集群管理器请求资源以启动执行程序。集群管理器启动执行器。驱动程序进程通过用户应用程序运行。根据 RDD 上的操作和转换,任务被发送给执行者。执行者运行任务并保存结果。如果任何一个 worker 崩溃,它的任务将被发送到不同的 executor 以再次处理。在“Learning Spark:Lightning-Fast Big Data Analysis”一书中,他们谈到了 Spark 和容错:

Spark 通过重新执行失败或缓慢的任务来自动处理失败或缓慢的机器。例如,如果运行 map() 操作的分区的节点崩溃了,Spark 会在另一个节点上重新运行它;即使节点没有崩溃,只是比其他节点慢得多,Spark 也可以抢先在另一个节点上启动任务的“推测性”副本,并在完成后获取其结果。

使用驱动程序中的 SparkContext.stop() 或者如果主方法退出/崩溃,所有执行程序将被终止,集群资源将由集群管理器释放。

你的问题

当执行器启动时,它们向驱动程序注册自己,然后它们直接通信。工作人员负责向集群管理器传达其资源的可用性。在 YARN 集群中,您可以使用 --num-executors 来做到这一点。在独立集群中,除非您使用 spark.executor.cores 并且工作人员有足够的核心来容纳多个执行程序,否则每个工作人员将获得一个执行程序。 (正如@JacekLaskowski 指出的那样,--num-executors 不再在 YARN 中使用 https://github.com/apache/spark/commit/16b6d18613e150c7038c613992d80a7828413e66)您可以使用 --executor-cores 分配每个执行程序的核心数--total-executor-cores 是每个应用程序的最大执行器核心数 正如 Sean Owen 在此线程中所说:“没有充分的理由在每台机器上运行多个工作程序”。例如,您将有许多 JVM 坐在一台机器上。

更新

我无法测试这种情况,但根据文档:

示例 1:Spark 将贪婪地获取调度程序提供的尽可能多的核心和执行器。所以最后你会得到 5 个执行器,每个执行器有 8 个核心。

示例 2 到 5:Spark 将无法在单个 worker 中分配尽可能多的核心,因此不会启动任何执行程序。


多么棒的答案!谢谢@Marco。根据 github.com/apache/spark/commit/… --num-executors 不再在 YARN 中使用。
@Marco 感谢您的出色回答。您能否在驱动程序运行时扩展集群管理器的持续角色? ...它必须处理驾驶员或工人或两者都崩溃或停止响应的情况,以了解可用的资源。
@lain 驱动程序联系集群管理器以分配资源,并请求集群管理器启动执行程序
@astro_asz 一个节点是一台通常只有一个工作人员的机器(例如,没有充分的理由拥有一个以上的工作人员......但这是可能的)。一个工人有许多执行者。
很好的答案。您可以在此处找到有关 spark 内部结构的详细信息 github.com/JerryLead/SparkInternals/blob/master/EnglishVersion/…
S
Sharhabeel Hamdan

这是 Apache Spark 在内部工作的方式:

https://i.stack.imgur.com/1y2zm.png


这张图是哪里来的?有参考吗?
我认为这张图来自 analyticsvidhya.com/blog/2021/08/…