Spark原理概述
原文来自我的个人网站:http://www.itrensheng.com/archives/Spark_basic_knowledge
一. Spark出现的背景
在Spark出现之前,大数据计算引擎主要是MapReduce。HDFS + MapReduce的组合几乎可以实现所有的大数据应用场景。MR框架抽象程度比较高,需要我们编写Map和Reduce两个步骤(MapReduce 框架其实包含5 个步骤:Map、Sort、Combine、Shuffle以及Reduce)
每个Map和Reduce之间需要进行Shuffle(这步操作会涉及数量巨大的网络传输,需要耗费大量的时间)。由于 MapReduce 的框架限制,一个 MapReduce 任务只能包含一次 Map 和一次 Reduce,计算完成之后,MapReduce会将运算中间结果写回到磁盘中,供下次计算使用。
二.Spark简介
Spark是由加州大学伯克利分校AMP实验室开源的分布式大规模数据处理通用引擎,具有高吞吐、低延时、通用易扩展、高容错等特点。Spark内部提供了丰富的开发库,集成了数据分析引擎Spark SQL、图计算框架GraphX、机器学习库MLlib、流计算引擎Spark Streaming
相比于MapReduce的计算模型,Spark是将数据一直缓存在内存中,直到计算得到最后的结果,再将结果写入到磁盘,所以多次运算的情况下,Spark省略了多次磁盘IO。
对比 | MapReduce | Spark |
---|---|---|
速度 | 处理数据需要连续的读写磁盘 | 是MapReduce的10到100倍 |
编码难度 | 程序员来赋值每一步 | RDD高可用,失败重试 |
及时性 | 不适合做OLAP,只适合批处理 | 能兼顾批处理和OLAP |
调度 | 使用外部的调度,如Oozie | 自带调度,也可使用外部调度 |
编程语言 | Java | Scala |
SQL支持 | 本身不提供,需要外部查询引擎,如Hive | 自带Spark SQL |
可扩展性 | 最大支持14000个节点 | 最大8000节点 |
机器学习 | 外部依赖Mahout | 自带Spark MLlib |
缓存 | 能不缓存到内存中 | 可以缓存到内存中 |
安全性 | 安全特性比Spark广泛 | 不如MapReduce |
三. Spark系统架构
Driver:
一个Spark job运行前会启动一个Driver进程,也就是作业的主进程,负责解析和生成各个Stage,并调度Task到Executor上
SparkContext:
程序运行调度的核心,高层调度去DAGScheduler划分程序的每个阶段,底层调度器TaskScheduler划分每个阶段具体任务
Worker:
也就是WorkderNode,负责执行Master所发送的指令,来具体分配资源并执行任务
Executer:
负责执行作业。如图中所以,Executer是分步在各个Worker Node上,接收来自Driver的命令并加载Task
DAGScheduler:
负责高层调度,划分stage并生产DAG有向无环图
TaskScheduler:
负责具体stage内部的底层调度,具体task的调度和容错
Job:
每次Action都会触发一次Job,一个Job可能包含一个或多个stage
Stage:
用来计算中间结果的Tasksets。分为ShuffleMapStage和ResultStage,出了最后一个Stage是ResultStage外,其他都是ShuffleMapStage。ShuffleMapStage会产生中间结果,是以文件的方式保存在集群当中,以便能够在不同stage种重用
Task:
任务执行的工作单位,每个Task会被发送到一个节点上,每个Task对应RDD的一个partition.
RDD:
是以partition分片的不可变,Lazy级别数据集合 算子
Transformation:
由DAGScheduler划分到pipeline中,是Lazy级别的,不会触发任务的执行
Action:
会触发Job来执行pipeline中的运算
四. Spark Job执行流程
spark = SparkSession\
.builder\
.appName("PythonWordCount")\
.getOrCreate() lines = spark.read.text(sys.argv[1]).rdd.map(lambda r: r[0])
counts = lines.flatMap(lambda x: x.split(' ')) \
.map(lambda x: (x, 1)) \
.reduceByKey(add)
output = counts.collect()
for (word, count) in output:
print("%s: %i" % (word, count)) spark.stop()
- 使用spark-submit向集群提交一个job之后,就会启动一个Driver进程。Driver进程会根据deploy-mode不同而不同,可能是本地启动,也可能是集群中的节点
- Driver进程向资源管理器Resource Manager(可以是Standalone、Mesos或YARN)注册并申请运行Executor资源,如YARN会根据spark-submit中申请的参数来为Spark作业设置对应的资源参数,并在集群中的各个节点上分配对应数量的Executor进程
- Driver进程会将整个Job拆分为多个Stage,一个Stage可能包含多个Task,并将这些Task分配到第二步中申请到的Executor进程中执行。Task是执行的最小Unit。当一个Stage所属的所有Task都执行完成之后,会在各个节点的磁盘文件中记录中间结果并继续执行后续的Stage。
四. RDD
定义:
RDD 是 Spark 的计算模型。RDD(Resilient Distributed Dataset)叫做弹性的分布式数据集合,是 Spark中最基本的数据抽象,它代表一个不可变、只读的,被分区的数据集。
可以将 RDD 理解为一个分布式对象集合,本质上是一个只读的分区记录集合。每个 RDD可以分成多个分区,每个分区就是一个数据集片段。一个 RDD 的不同分区可以保存到集群中的不同结点上,从而可以在集群中的不同结点上进行并行计算。
五大特性:
分区列表:RDD是分区的,且每一个分区都会被一个Task所处理,所以Job的并行执行能力取决于分区多少。默认情况下,RDD的分区数是集成自父RDD,这个值也可以在创建RDD的时候在代码中指定
计算函数:每个分区都有一个计算函数,这个计算函数是以分片为基本单位的。如在RDD的宽依赖场景下,将宽依赖划分为Stage,而Stage使用BlockManager获取分区数据并根据计算函数来split对应的Block
存在依赖关系:RDD经过计算任务每次都会转化为一个不可变的新的RDD。因为有依赖关系,所以当前一个RDD失败的时候,Spark会根据依赖关系重新计算前一个失败的RDD,而不是所有的RDD。
KV数据类型分区器:控制分区策略和分区数,每个KV形式的RDD都有Partitioner属性,来控制RDD如何分区。
5.优先位置列表:每个分区都有优先位置列表,用于存储Partition的优先位置。如果是读取HDFS,那就是每个Block的优先位置。
RDD的依赖关系
依赖关系分为宽依赖(Wide Dependency)和窄依赖(Narraw Dependency)。
宽依赖:子RDD分区依赖父RDD的所有分区。如果子RDD部分分区甚至全部分区数据损坏或丢失,需要从所有父RDD重新计算,相对窄依赖而言付出的代价更高,所以应尽量避免宽依赖的使用
窄依赖:父RDD的分区只对应一个子RDD的分区。如果子RDD只有部分分区数据损坏或者丢失,只需要从对应的父RDD重新计算恢复如果子RDD只有部分分区数据损坏或者丢失,只需要从对应的父RDD重新计算恢复
类型
RDD可以分为2中类型:Transformation 和 Action
Transformation 操作不是马上提交 Spark 集群执行的,Spark 在遇到 Transformation操作时只会记录需要这样的操作,并不会去执行,需要等到有 Action 操作的时候才会真正启动计算过程进行计算.
针对每个 Action,Spark 会生成一个 Job,从数据的创建开始,经过 Transformation, 结尾是 Action 操作.这些操作对应形成一个有向无环图(DAG),形成 DAG 的先决条件是最后的函数操作是一个Action
五. 缓存
Spark 本身就是一个基于内存的迭代式计算,当某个RDD的计算结果会被多次重复使用的时候,缓存就很有必要(尤其是对于整个血统很长的计算任务)。如果程序从头到尾只有一个 Action 操作且子RDD只依赖于一个父RDD 的话,就不需要使用 cache 这个机制。
Spark 可以使用 persist 和 cache 方法将任意 RDD 缓存到内存、磁盘文件系统中。缓存是容错的,如果一个 RDD 分片丢失,则可以通过构建它的转换来自动重构。被缓存的 RDD 被使用时,存取速度会被大大加速。一般情况下,Executor 内存的 60% 会分配给 cache,剩下的 40% 用来执行任务
MEMORY_ONLY: 使用未序列化的Java对象格式,将数据保存在内存中。如果内存不够存放所有的数据,则某些分区的数据就不会进行持久化。那么下次对这个RDD执行算子操作时,那些没有被持久化的数据,需要从源头处重新计算一遍。这是默认的持久化策略,使用cache()方法时,实际就是使用的这种持久化策略。
MEMORY_ONLY_SER: 基本含义同MEMORY_ONLY。唯一的区别是,会将RDD中的数据进行序列化,RDD的每个partition会被序列化成一个字节数组。这种方式更加节省内存,从而可以避免持久化的数据占用过多内存导致频繁GC。
MYMORY_AND_DISK: 使用未序列化的Java对象格式,优先尝试将数据保存在内存中。如果内存不够存放所有的数据,会将数据写入磁盘文件中,下次对这个RDD执行算子时,持久化在磁盘文件中的数据会被读取出来使用。
MEMORY_AND_DISK_SER: 基本含义同MEMORY_AND_DISK。唯一的区别是,会将RDD中的数据进行序列化,RDD的每个partition会被序列化成一个字节数组。这种方式更加节省内存,从而可以避免持久化的数据占用过多内存导致频繁GC。
DISK_ONLY: 使用未序列化的Java对象格式,将数据全部写入磁盘文件中。
MEMORY_ONLY_2/MEMORY_AND_DISK_2: 对于上述任意一种持久化策略,如果加上后缀_2,代表的是将每个持久化的数据,都复制一份副本,并将副本保存到其他节点上。这种基于副本的持久化机制主要用于进行容错。假如某个节点挂掉,节点的内存或磁盘中的持久化数据丢失了,那么后续对RDD计算时还可以使用该数据在其他节点上的副本。如果没有副本的话,就只能将这些数据从源头处重新计算一遍了。
OFF_HEAP(experimental) : RDD的数据序例化之后存储至Tachyon。相比于MEMORY_ONLY_SER,OFF_HEAP能够减少垃圾回收开销、使得Spark Executor更“小”更“轻”的同时可以共享内存;而且数据存储于Tachyon中,Spark集群节点故障并不会造成数据丢失,因此这种方式在“大”内存或多并发应用的场景下是很有吸引力的。需要注意的是,Tachyon并不直接包含于Spark的体系之内,需要选择合适的版本进行部署;它的数据是以“块”为单位进行管理的,这些块可以根据一定的算法被丢弃,且不会被重建。
Spark原理概述的更多相关文章
- 大数据技术之_19_Spark学习_05_Spark GraphX 应用解析 + Spark GraphX 概述、解析 + 计算模式 + Pregel API + 图算法参考代码 + PageRank 实例
第1章 Spark GraphX 概述1.1 什么是 Spark GraphX1.2 弹性分布式属性图1.3 运行图计算程序第2章 Spark GraphX 解析2.1 存储模式2.1.1 图存储模式 ...
- Spark原理分析目录
1 Spark原理分析 -- RDD的Partitioner原理分析 2 Spark原理分析 -- RDD的shuffle简介 3 Spark原理分析 -- RDD的shuffle框架的实现概要分析 ...
- linux软中断与硬中断实现原理概述
linux软中断与硬中断实现原理概述. 1.软中断通过open_softirq注册一个软中断处理函数,即在软中断向量表softirq_vec数组中添加新的软中断处理action函数. 2.调用rais ...
- 大数据技术之_19_Spark学习_03_Spark SQL 应用解析 + Spark SQL 概述、解析 、数据源、实战 + 执行 Spark SQL 查询 + JDBC/ODBC 服务器
第1章 Spark SQL 概述1.1 什么是 Spark SQL1.2 RDD vs DataFrames vs DataSet1.2.1 RDD1.2.2 DataFrame1.2.3 DataS ...
- 大数据技术之_19_Spark学习_04_Spark Streaming 应用解析 + Spark Streaming 概述、运行、解析 + DStream 的输入、转换、输出 + 优化
第1章 Spark Streaming 概述1.1 什么是 Spark Streaming1.2 为什么要学习 Spark Streaming1.3 Spark 与 Storm 的对比第2章 运行 S ...
- InspectIT_EUM 实现原理概述
在Git上查看 InspectIT 实现原理概述: 实现原理详解: 1.jsAgent如何注入到浏览器 通过ASM框架修改HttpService.service()方法,加入相关逻辑,对每一个Htt ...
- Spark SQL概念学习系列之Spark SQL概述
很多人一个误区,Spark SQL重点不是在SQL啊,而是在结构化数据处理! Spark SQL结构化数据处理 概要: 01 Spark SQL概述 02 Spark SQL基本原理 03 Spark ...
- MOOC 编译原理笔记(一):编译原理概述以及程序设计语言的定义
编译原理概述 什么是编译程序 编译程序指:把某一种高级语言程序等价地转换成另一张低级语言程序(如汇编语言或机器代码)的程序. 高级语言程序-翻译->机器语言程序-运行->结果. 其中编译程 ...
- 第1章 Spark SQL概述
第1章 Spark SQL概述 1.1 什么是Spark SQL Spark SQL是Spark用来处理结构化数据的一个模块,它提供了一个编程抽象叫做DataFrame并且作为分布式SQL查询引擎的作 ...
随机推荐
- Centos7安装python3.6.5
安装python3.6.5,原来的python2.7.5并存 准备环境: 登录你的linux虚拟机或者云服务器,进入命令行界面如下图: 进入这样的窗口就是远程登录成功,我这里使用的是远程连接工具xsh ...
- 一个小时学会jQuery(转载)
目录 一.jQuery简介与第一个jQuery程序 1.1.jQuery简介 1.2.jQuery特点 1.3.jQuery版本 1.4.获得jQuery库 1.5.第一个jQuery程序 二.jQu ...
- centos7添加搜狗输入法
https://www.cnblogs.com/eeexu123/p/9259430.html https://blog.csdn.net/jpch89/article/details/8190380 ...
- DTU DeepLearning: exercise 7
torch activation functions: sigmoid, relu, tanh, softplus. https://morvanzhou.github.io/tutorials/ma ...
- CSS的长度单位
对于css的长度单位真的有必要知道一下.那么css长度单位有哪些呢? 分成两大类: 1.绝对单位:不会因为其他元素的尺寸变化而变化.坚持自我. 2.相对单位:没有一个确定的值,而是由其他元素的尺寸影响 ...
- python itertool 浅谈迭代工具
1.概述 Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数. 首先,我们看看itertools提供的几个“无限”迭代器: import itertools natuals ...
- util之Map
1.定义 Map<String, Integer> map = new HashMap<String,Integer>(); 2.判断map中是否存在某个键的值: if(map ...
- jvm(3):JVM调优
typora-root-url: ./ JVM调优思路 目的:减少full GC次数.减少STW时间(一次GC的时间) 手段: 打印GC日志-XX:+PrintGCDetails -XX:+Print ...
- jdk8-》日期时间及其格式处理类特性
一.JDK8之时间⽇期处理类 核⼼类: LocalDate:不包含具体时间的⽇期. LocalTime:不含⽇期的时间. LocalDateTime:包含了⽇期及时间. LocalDate 常⽤API ...
- HTML学习(8)超链接
<a href="url">链接文本或图片</a> 可以使用id属性来访问标记的地方,例: <a id="tip">被访问的 ...