spark中local模式与cluster模式使用场景_Spark内核及通信框架概述-针对面试(后面有源码分析)...

v2-6630858406051eaccd633d4bf6a5dcac_1440w.jpg?source=172ae18b

Spark 内核概述

Spark内核泛指Spark的核心运行机制,包括Spark核心组件的运行机制、Spark的任务调度机制、Spark的内存管理机制、Spark核心功能的运行原理等。熟练掌握Spark内核原理能够帮助我们更好的完成Spark代码设计,并且在项目运行时出现问题可以快速的锁定问题的症结。

Spark 核心组件回顾

Cluster-Manager(Master,ResourceManager)--Spark的集群管理器,主要负责对整个集群资源的分配与管理。

Cluster Manager 在 Yarn 部署模式下为 ResourceManager; 在 Mesos 部署模式下为 Mesos Master; 在 Standalone 部署模式下为 Master。

Cluster Manager 分配的资源属于一级分配, 它将各个 Worker 上的内存, CPU 等资源分配给 Application, 但并不负责对 Executor 的资源的分配。

Worker(Worker,NodeManager:Yarn部署模式)--主要负责以下工作:

  • 将自己的内存、CPU等资源通过注册机制告知Cluster-Manager;
  • 创建Executor进程;
  • 将资源和任务进一步分配给Executor;
  • 同步资源信息、Executor状态信息给ClusterManager等;

Driver --Spark的驱动器节点,用于执行 Spark 任务中的main方法、实际代码的执行工作。

Driver在Spark作业执行时负责以下工作:

  • 将用户程序转化为Job;
  • 在Executor之间调度Task;
  • 跟踪Executor的执行情况;
  • 通过UI展示查询运行情况;

Executor --负责运行Job中具体的Task,Task之间相互独立。Spark应用启动的时候Executor节点同时被启动,并且伴随Spark应用的整个生命周期。如果Executor节点发生了故障,Spark应用可以继续执行,会将出错节点上的任务调度到其他Executor上继续执行。

Executor核心功能

  • 负责运行组成spark应用的Task,并将结果返回给Driver
  • Executor通过块管理器Block-Manager为用户程序中需要缓存的RDD提供内存式存储。RDD的数据是直接缓存到Executor进程内的,所以Task可以在运行时充分利用缓存数据加速运算。

Application --用户使用spark提供的API编写的应用程序。

  • Application通过spark API进行RDD的转换和DAG的构建,并通过Driver将Application注册到Cluster-Manager;
  • Cluster-manager根据Application的资源需求将Executor、CPU、memory分配给Application;
  • Driver将Executor等资源分配给每一个Task,Application最后通过Driver通知Executor运行任务;

下面看一张图理解一下spark的通用运行流程(不管何种模式,只是核心步骤)

v2-5c2b9f2ecf4e72586f246f1f2d9a72f5_b.jpg
简单的理解一下,后面会特别详细的扣扣整个流程的细节
  1. 任务提交后,都会先启动Driver程序;
  2. 随后Driver想集群注册应用程序;
  3. 之后Cluster-Manager根据此任务的配置文件分配Executor并启动该Application;
  4. 当Driver所需的资源全部满足后,Driver开始执行main()函数,spark转换为懒执行,当执行到action算子时开始反响推算,根据宽依赖进行stage的划分,随后每一个stage对应一个TaskSet(包含多个task);
  5. 根据本地化原则,Task会被分发到指定的Executor去执行,在任务执行的过程中,Executor也会不断与Driver进行通信,报告任务运行情况;

Spark 通信框架概述

spark内置RPC框架

spark在各个组件之间的消息互通、用户文件与Jar包上传、节点间的shuffle过程、Block数据的复制与备份等地方都要涉及通信。在spark1.3版本之前各组件之间通过Akka通信,在spark1.3的时候引入了Netty通信框架,Akka要求message发送端和接收端有相同的版本, 所以为了避免 Akka 造成的版本问题,并给用户的应用更大灵活性,决定使用更通用的 RPC 实现,也就是现在的 Netty 来替代 Akka。从spark2.0开始Akka被彻底移除。

Actor模型

v2-a44671cde3c2fe21affa87244f0a372a_b.jpg
Netty 借鉴了 Akka 的 Actor 模型

Spark通信框架中各个组件(Client/Master/Worker)可以认为是一个个独立的实体,各个实体之间通过消息来进行通信。

v2-17b83f64d5bcb2dc7465a4a02d96a22a_b.jpg

Endpoint(Client/Master/Worker)有 1 个 InBox 和 N 个 OutBox(N>=1,N取决于当前 Endpoint 与多少其他的 Endpoint 进行通信,一个与其通讯的其他Endpoint 对应一个 OutBox),Endpoint 接收到的消息被写入 InBox,发送出去的消息写入 OutBox 并被发送到其他 Endpoint 的 InBox 中。

Spark Netty 通信架构解析

Netty 官网: https:// netty.io/

v2-f83745a5637f2fceaeccbc986389d91d_b.jpg
  • RpcEndpoint:RPC 端点。

Spark 针对每个节点(Client/Master/Worker)都称之为一个 RpcEndpoint ,且都实现 RpcEndpoint接口,内部根据不同端点的需求,设计不同的消息和不同的业务处理,如果需要发送(询问)则内部调用 Dispatcher 的对应方法;

RpcEndpoint 接收消息;
RpcEndpointRef 发送消息;
RpcEndpointRef的具体实现类是: NettyRpcEndpointRef

v2-728711b6f3826ec922c363e3fc369344_b.jpg
  • RpcEnv: Rpc 上下文(Rpc 环境)
每个RpcEndpoint运行时依赖的上下文环境称为 RpcEnv
  • Dispatcher:消息分发器
RPC 端点需要发送消息或者从远程 RPC 端点接收到的消息,分发至对应的指令收件箱/发件箱。
如果指令接收方是自己则存入收件箱,如果指令接收方不是自己则放入发件箱
// class NettyRpcEnv
  • Inbox:指令消息收件箱。
一个本地 RpcEndpoint 对应一个收件箱
  • RpcEndpointRef:RpcEndpointRef 是对远程 RpcEndpoint 的一个引用。
当我们需要向一个具体的 RpcEndpoint 发送消息时,一般我们需要获取到该RpcEndpoint 的引用,然后通过该引用发送消息。
  • OutBox:指令消息发件箱。
对于当前 RpcEndpoint 来说,一个目标 RpcEndpoint 对应一个当前的发件箱,如果向多个目标 RpcEndpoint 发送信息,则有当前会有多个 OutBox。当消息放入 Outbox 后,紧接着通过 TransportClient 将消息发送出去。消息放入发件箱以及发送过程是在同一个线程中进行;
  • RpcAddress:表示远程的RpcEndpointRef的地址,Host + Port
  • TransportClient:Netty通信客户端
一个 OutBox 对应一个 TransportClient,TransportClient 不断轮询OutBox,根据 OutBox 消息的 receiver 信息,请求对应的远程 TransportServer;
  • TransportServer:Netty 通信服务端
一个 RpcEndpoint 对应一个 TransportServer,接受远程消息后调用 Dispatcher 分发消息至自己的收件箱,或者对应的发件箱;
  • 再来一张图感受一下

v2-4ca6546102707abd39bde1ac7e09bd54_b.jpg

Spark 集群启动流程分析(本章分析Standalone模式的启动流程)

v2-b12e15ae6902c1b7ecba369dcca39987_b.jpg
Master,Worker启动流程
  1. start-all.sh脚本,实际是执行java -cp Master和java -cp Worker;
  2. Master启动时首先创建一个RpcEnv对象,负责管理所有通信逻辑;
  3. Master通过RpcEnv对象创建一个Endpoint,Master就是一个Endpoint,Worker可以与其进行通信;
  4. Worker启动时也是创建一个RpcEnv对象;
  5. Worker通过RpcEnv对象创建一个Endpoint;
  6. Worker通过RpcEnv对象建立到Master的连接,获取到一个RpcEndpointRef对象,通过该对象可以与Master通信;
  7. Worker向Master注册,注册内容包括主机名、端口、CPU Core数量、内存数量;
  8. Master接收到Worker的注册,将注册信息维护在内存中的Table中,其中还包含了一个到Worker的RpcEndpointRef对象引用;
  9. Master回复Worker已经接收到注册,告知Worker已经注册成功;
  10. Worker端收到成功注册响应后,开始周期性向Master发送心跳。
  • start-master.sh Master 启动脚本分析
启动 
  • start-slaves.sh Worker 启动脚本分析
启动 
  • Master 启动源码分析
private
  • RpcEnv的创建
真正的创建是调用NettyRpcEnvFactory的create方法创建的.
创建 NettyRpcEnv的时候, 会创建消息分发器, 收件箱和存储远程地址与发件箱的 Map
  • RpcEnv.scala源码分析
def 
  • Master伴生类(Master 端的 RpcEndpoint 启动)
Master是一个RpcEndpoint,他的生命周期方法是:constructor -> onStart -> receive* -> onStop
  • onStart 主要代码片段
// 创建 WebUI 服务器
  • Worker启动源码分析
org.apache.spark.deploy.worker.Worker
  • Worker伴生对象--启动流程基本和 Master 一致
private
  • Worker伴生类 --onStart 方法
override 
  • registerWithMaster( ) 方法关键代码:
// 向所有的 Master 注册
  • tryRegisterAllMasters() 方法
private 
  • registerWithMaster 方法
private 
  • Master的receiveAndReply方法
// 处理 Worker 的注册信息
  • worker的handleRegisterResponse方法
case 
  • Worker的receive方法:
case 
  • Master的receive方法:
case 

---------Worker启动完成-------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值