spark编程基础(一)--spark的设计与运行原理

基本概念和架构设计

基本概念

RDD:弹性分布式数据集,是分布式内存的一个抽象概念,提供了一种高度受限的共享内存模型。
DAG:有向无环图,反映RDD之间的依赖关系。
Executor:是运行在工作节点的进程,负责运Task。
Task:运行在Executor上的工作单位,一个Task为一个线程。
Job:一个Job包含多个RDD及作用于相应的RDD上的各种操作。
Stage:是Job的基本调度单位,一个Job会分为多组Task,每组Task被称为Stage,或者也被称为TaskSet,代表了一组关联的,相互之间没有Shuffle依赖关系的任务组成的任务集。
Application:用户编写的Spark应用程序。

架构设计

在这里插入图片描述
ClusterManager:集群资源管理器
WorkerNode:运行作业任务的工作节点
Driverprogram:每个应用的任务控制节点
Executor:每个工作节点上负责具体任务的执行进程

优点:

  1. 利用多线程来执行具体的任务减少任务的具体开销。
  2. Executor中有一个BlockManager存储模块,会将内存和磁盘共荣作为存储设备,有效减少IO开销。计算的全过程在内存中执行。spark是基于内存计算。

Spark中各种概念之间的相互关系

一个Application由一个Driver和若干个Job构成,一个Job有多个Stage构成,一个Stage由多个没有Shuffle关系的Task组成。
当执行一个Application时,Driver会想资源管理器申请资源,启动Executor,并向Executor发送应用程序代码和文件,然后在Executor上执行Task,运行结束后,执行结构会返回Driver,或者写到HDFS或者其他数据库中。

spark运行基本流程

在这里插入图片描述

  1. 为应用构建起基本的运行环境,即有Driver创建一个SparkContext进程资源的申请、任务的分配和监控。sc是集群的连接通道。
  2. 资源管理器为Executor分配资源,并启动Executor。
  3. SparkContext根据RDD的依赖关系构建DAG图,DAG图提交给DAGScheduler解析成Stage,然后把一个个TaskSet提交给底层调度器TaskSchedular处理。Executor向SparkContext申请TaskScheduler将Task发放给Executor运行并提供应用程序代码。计算向数据靠拢:Task优先发送给数据所在的WorkNode。
  4. Task在Executor运行把执行结构反馈给TaskScheduler,然后返回给DAGScheduler,运行完毕后写入数据并释放所有资源。

Spark运行构架特点

  • 每个Application都有自己专属的Executor进程,并且该进程在该Application执行期间一直驻留,Excutor进程以多线程方式运行Task,所以启动开销小。
  • Spark运行过程与资源管理器无关(yarn, mesos等)只要能获取Executor进程并保持通信即可。
  • Task采用数据本地性(计算向数据靠拢)和推测执行(数据所在节点资源已满,是否在其他节点执行)等优化机制。

RDD

RDD概念

目的: 为了避免计算的结果反复写入磁盘,减小磁盘开销。
RDD本质上是一个只读的分区记录集合,在不同的节点同同时计算,所以计算速度快。RDD不能直接修改,只能基于稳定的物理存储中的数据集创建RDD,或者通过在其他RDD上执行确定的转化操作而创建得到新的RDD。

RDD操作

RDD操作分为“动作(Action)”和“转换(Transformation)”。
RDD提供的转换接口是类似于map, filter, groupBy, join等粗粒度的数据转换操作,而不是针对某个数据项的细粒度修改(不适合网页爬虫)。

RDD执行过程

  1. RDD读入外部数据源进行创建。
  2. RDD经过一系列的“转换”操作,每一次都会产生不同的RDD供给下一个转换操作使用。
  3. 最后一个RDD经过“动作”操作进行转换,并输出到外部数据源。

惰性机制:转换时不发生实际的计算,只记录转换的轨迹,只有当发生“动作”时,才会从头开始实际计算转换操作。
在这里插入图片描述
这一系列处理称为一个Lineage(血缘关系),即DAG拓扑排序的结果。
优点:惰性调用、管道化、避免同步等待、不需要保存中间结果、每次操作变得简单。

RDD特性

  1. 高效的容错性
  2. 中间结果持久化到内存,数据在内存中的多个RDD操作之间进行传递,避免了不必要的读写磁盘开销。
  3. 存放的数据可以是Java对象,避免了不必要的对象序列化和反序列化。

Spark采用RDD以后能够实现高效计算的原因:
5. 现有容错机制:数据复制或者记录日志(记录转换轨迹/DAG图,轨迹为粗粒度,所以日志量较少,代价低。)
6. RDD:血缘关系、重新计算丢失分区、无需回滚系统、重算过程在不同节点之间并行、只记录粗粒度的操作。

RDD依赖关系和运行过程

依赖关系:

窄依赖: 表现为一个父RDD的分区对应于一个子RDD的分区,或多个父RDD的分区对应于一个子RDD的分区。如map.filter, Union, join。
宽依赖: 表现为存在一个父RDD的一个分区对应于一个子RDD的多个分区。如groupByKey, join。
宽依赖恢复损坏的分区代价较高。

Stage的划分:
Spark通过分析各个RDD的依赖关系生成了DAG再通过分析各个RDD中的分区之间的依赖关系来决定如何划分Stage。

具体划分方法:
在DAG中进行反向解析,遇到宽依赖就断开。
遇到宽依赖就把当前的RDD加入到Stage中。
将窄依赖尽量划分在同一个Stage中,可以实现流水线计算。

RDD运行过程:

  1. 创建RDD对象
  2. SparkContext负责计算RDD之间的依赖关系,构建DAG
  3. DAGScheduler负责把DAG图分解为多个Stage每个Stage中包含了多个task,每个Task会被TaskScheduler分发给各个WorkerNode上的Executor去执行。采用计算向数据靠拢方式。

Spark的部署和应用方式

Spark的Streaming是基于小批量数据集批量的模拟流式计算

不同的计算框架统一运行在YARN中,可以带来如下好处

  1. 计算资源按需伸缩:不同的计算框架的峰谷在不同时段
  2. 不用负载应用混搭,集群利用率高
  3. 共享底层存储,避免数据跨集群迁移

Hadoop是一个生态系统,包含许多组件。Spark是一个计算框架,其优越点在于计算性能优越,能够取代Hadoop的MapRudece。

发布了21 篇原创文章 · 获赞 0 · 访问量 398

猜你喜欢

转载自blog.csdn.net/leemusk/article/details/103442151