- 三、Spark核心原理:分布式计算引擎。
- 3.1 RDD 编程模型
- 3.1 Spark 进程模型
- 1、Spark(集群) 启动流程
- 2、Spark 的执行/运行/处理流程(*15)
- 追问1:Driver 作用?
- 追问2:`DAGScheduler、TaskScheduler 和 SchedulerBackend` 作用?
- 追问3:DAGscheduler干了什么活?(*2)
- 追问4:为什么要区分宽依赖和窄依赖?
- 追问5:如何连起来?
- 追问5:Job、Task、Stage分别说下?(*2)
- 追问6:特别大的数据,怎么发送到excutor中?
- 3.2 调度系统
- 1、Spark怎么进行调度的?(*10)
- 追问1:资源调度和任务调度的关系?
- 3.3 存储系统
- 3.4 Shuffle 管理
- 1、Shuffle 是什么?(*2)
- 2、Spark shuffle演化?
- 3.5 内存管理
- 参考
我还会用一个又一个有趣的故事,以轻松诙谐、深入浅出的方式为你讲解 Spark 核心原理,包括 RDD 编程模型、Spark 进程模型、 调度系统、存储系统、Shuffle 管理、内存管理等等,从而让你像读小说一样去弄懂 Spark。3.1 RDD 编程模型 3.1 Spark 进程模型 1、Spark(集群) 启动流程
1、启动Master进程,启动完会解析slaves配置文件,根据host启动相应节点及里面Worker。
2、Worker启动后,把注册信息发送给Master。
3、Master收到注册信息保存到内存和磁盘,并把自己的URL(masterURL)响应给Worker。
4、Worker收到Master的URL信息后,调用定时器,定时向Master发送心跳信息。
-
Step1:启动Driver,构造DAG。
首先,Spark 应用程序启动在自己的 JVM 进程里,即 Driver 进程,启动后调用 SparkContext 初始化执行配置和输入数据。SparkContext 启动 DAGScheduler 构造执行的 DAG 图,切分成最小的执行单位也就是计算任务。 -
Step2:Driver请求资源,通知Worker。
然后 Driver 向 Cluster Manager 请求计算资源,用于 DAG 的分布式计算。Cluster Manager 收到请求以后,将 Driver 的主机地址等信息通知给集群的所有计算节点 Worker。 -
Step3:Worker收到,向Driver通报可用资源。
Worker 收到信息以后,根据 Driver 的主机地址,跟 Driver 通信并注册,然后根据自己的空闲资源向 Driver 通报自己可以领用的任务数。Driver 根据 DAG 图开始向注册的 Worker 分配任务。 -
Step4:Worker收到任务,启动Executor 执行任务。
Worker 收到任务后,启动 Executor 进程开始执行任务。Executor 先检查自己是否有 Driver 的执行代码,如果没有,从 Driver 下载执行代码,通过 Java 反射加载后开始执行。
Driver 最核心的作用在于,解析用户代码、构建计算流图,然后将计算流图转化为分布式任务,并把任务分发给集群中的执行进程交付运行。换句话说,Driver 的角色是拆解任务、派活儿,而真正干活儿的“苦力”,是执行进程。在 Spark 的分布式环境中,这样的执行进程可以有一个或是多个,它们也有专门的术语,叫作“Executor”。
追问2:DAGScheduler、TaskScheduler 和 SchedulerBackend 作用?DAGScheduler、TaskScheduler 和 SchedulerBackend 三对象是Driver 的给力帮手,通力合作,依次完成分布式任务调度的 3 个核心步骤,也就是:
- DAGScheduler、 根据用户代码构建计算流图;
- TaskScheduler :根据计算流图拆解出分布式任务;
- SchedulerBackend :将分布式任务分发到 Executors 中去。
从全局视角来看,DAGScheduler 是任务调度的发起者,DAGScheduler 以 TaskSet 为粒度,向 TaskScheduler 提交任务调度请求。TaskScheduler 在初始化的过程中,会创建任务调度队列,任务调度队列用于缓存 DAGScheduler 提交的 TaskSets。TaskScheduler 结合 SchedulerBackend 提供的 WorkerOffer,按照预先设置的调度策略依次对队列中的任务进行调度。
简而言之,DAGScheduler 手里有“活儿”,SchedulerBackend 手里有“人力”,TaskScheduler 的核心职能,就是把合适的“活儿”派发到合适的“人”的手里。由此可见,TaskScheduler 承担的是承上启下、上通下达的关键角色,这也正是我们将“塔斯克”视为斯巴克建筑公司元老之一的重要原因。
- 1、根据用户代码构建 DAG;
- 2、以 Shuffle 为边界切割 Stages;
- 3、基于 Stages 创建 TaskSets,并将 TaskSets 提交给 TaskScheduler 请求调度。
用一句话来概括从 DAG 到 Stages 的拆分过程,那就是:以 Actions 算子为起点,从后向前回溯 DAG,以 Shuffle *** 作为边界去划分 Stages。追问4:为什么要区分宽依赖和窄依赖?
- 窄依赖可以支持在同一个节点上链式执行多条命令,例如在执行了 map 后,紧接着执行 filter。相反,宽依赖需要所有的父分区都是可用的,可能还需要调用类似 MapReduce 之类的 *** 作进行跨节点传递。
- 从失败恢复的角度考虑,窄依赖的失败恢复更有效,因为它只需要重新计算丢失的父分区即可,而宽依赖牵涉到 RDD 各级的多个父分区。
……
1 App = n Job 1 Job = n Stage = n TaskSet 1 Stage = n Task 1 App = n1 job = n1*n2 Stage = n1*n2*n3 Task追问6:特别大的数据,怎么发送到excutor中?
……
3.2 调度系统 1、Spark怎么进行调度的?(*10)- 调度系统工作流程(主要 5 个步骤):
结合这 5 个步骤,我们深入分析了 Spark 调度系统的工作原理,我们可以从核心职责和核心原则这两方面来归纳:
Spark 调度系统的核心职责是,先将用户构建的 DAG 转化为分布式任务,结合分布式集群资源的可用性,基于调度规则依序把分布式任务分发到执行器 Executors;
Spark 调度系统的核心原则是,尽可能地让数据呆在原地、保持不动,同时尽可能地把承载计算任务的代码分发到离数据最近的地方(Executors 或计算节点),从而最大限度地降低分布式系统中的网络开销。
TaskScheduler 是按照任务的本地倾向性,来遴选出 TaskSet 中适合调度的 Tasks。追问1:资源调度和任务调度的关系?
资源调度和任务调度是分开的。
资源调度主要看哪些节点可以启动executors,是否能满足executors所需的cpu数量要求,这个时候,不会考虑任务、数据本地性这些因素。
资源调度完成之后,在任务调度阶段,spark负责计算每个任务的本地性,效果就是task明确知道自己应该调度到哪个节点,甚至是哪个executors。最后scheduler Backend会把task代码,分发到目标节点的目标executors,完成任务调度,实现数据不动代码动。
所以,二者是独立的,不能混为一谈哈~
3.3 存储系统……
3.4 Shuffle 管理 1、Shuffle 是什么?(*2)Shuffle 的本意是扑克牌中的“洗牌”,在大数据领域的引申义,表示的是集群范围内跨进程、跨节点的数据交换。
2、Spark shuffle演化?1、【Spark】Shuffle详解。
2、【Spark】数据倾斜
可暂时看【Spark】内存模型
……
-
背景
1、12 | 我们为什么需要Spark? -
基础
1、Spark启动流程:Spark运行架构解析 -
启动
1、spark启动流程1
2、Spark集群启动流程和任务提交流程
3、大数据分享Spark任务和集群启动流程 -
执行
1、13 | 同样的本质,为何Spark可以更高效? -
调度
1、05 | 调度系统:“数据不动代码动”到底是什么意思? -
内存
1、07 | 内存管理基础:Spark如何高效利用有限的内存空间?
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)