我阅读了 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。
在每个示例中,有多少执行者?每个执行器有多少个线程?几核?每个申请的执行人数量是如何决定的?它总是与工人的数量相同吗?
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 中分配尽可能多的核心,因此不会启动任何执行程序。
这是 Apache Spark 在内部工作的方式:
https://i.stack.imgur.com/1y2zm.png
不定期副业成功案例分享
--num-executors
不再在 YARN 中使用。