一,Spark优点特色web
做为大数据计算框架MapReduce的继任者,Spark具有如下优点特性。算法
1,高效性编程
不一样于MapReduce将中间计算结果放入磁盘中,Spark采用内存存储中间计算结果,减小了迭代运算的磁盘IO,并经过并行计算DAG图的优化,减小了不一样任务之间的依赖,下降了延迟等待时间。内存计算下,Spark 比 MapReduce 快100倍。微信
2,易用性数据结构
不一样于MapReduce仅支持Map和Reduce两种编程算子,Spark提供了超过80种不一样的Transformation和Action算子,如map,reduce,filter,groupByKey,sortByKey,foreach等,而且采用函数式编程风格,实现相同的功能须要的代码量极大缩小。架构
3,通用性app
Spark提供了统一的解决方案。Spark能够用于批处理、交互式查询(Spark SQL)、实时流处理(Spark Streaming)、机器学习(Spark MLlib)和图计算(GraphX)。框架
这些不一样类型的处理均可以在同一个应用中无缝使用。这对于企业应用来讲,就可以使用一个平台来进行不一样的工程实现,减小了人力开发和平台部署成本。机器学习
4,兼容性分布式
Spark可以跟不少开源工程兼容使用。如Spark可使用Hadoop的YARN和Apache Mesos做为它的资源管理和调度器,而且Spark能够读取多种数据源,如HDFS、HBase、MySQL等。
二,Spark基本概念
RDD:是弹性分布式数据集(Resilient Distributed Dataset)的简称,是分布式内存的一个抽象概念,提供了一种高度受限的共享内存模型。
DAG:是Directed Acyclic Graph(有向无环图)的简称,反映RDD之间的依赖关系。
Driver Program:控制程序,负责为Application构建DAG图。
Cluster Manager:集群资源管理中心,负责分配计算资源。
Worker Node:工做节点,负责完成具体计算。
Executor:是运行在工做节点(Worker Node)上的一个进程,负责运行Task,并为应用程序存储数据。
Application:用户编写的Spark应用程序,一个Application包含多个Job。
Job:做业,一个Job包含多个RDD及做用于相应RDD上的各类操做。
Stage:阶段,是做业的基本调度单位,一个做业会分为多组任务,每组任务被称为“阶段”。
Task:任务,运行在Executor上的工做单元,是Executor中的一个线程。
总结:Application由多个Job组成,Job由多个Stage组成,Stage由多个Task组成。Stage是做业调度的基本单位。
三,Spark架构设计
Spark集群由Driver, Cluster Manager(Standalone,Yarn 或 Mesos),以及Worker Node组成。对于每一个Spark应用程序,Worker Node上存在一个Executor进程,Executor进程中包括多个Task线程。
四,Spark运行流程
1,Application首先被Driver构建DAG图并分解成Stage。
2,而后Driver向Cluster Manager申请资源。
3,Cluster Manager向某些Work Node发送征召信号。
4,被征召的Work Node启动Executor进程响应征召,并向Driver申请任务。
5,Driver分配Task给Work Node。
6,Executor以Stage为单位执行Task,期间Driver进行监控。
7,Driver收到Executor任务完成的信号后向Cluster Manager发送注销信号。
8,Cluster Manager向Work Node发送释放资源信号。
9,Work Node对应Executor中止运行。
五,Spark部署模式
Local:本地运行模式,非分布式。
Standalone:使用Spark自带集群管理器,部署后只能运行Spark任务。
Yarn:Haoop集群管理器,部署后能够同时运行MapReduce,Spark,Storm,Hbase等各类任务。
Mesos:与Yarn最大的不一样是Mesos 的资源分配是二次的,Mesos负责分配一次,计算框架能够选择接受或者拒绝。
六,RDD数据结构
RDD全称Resilient Distributed Dataset,弹性分布式数据集,它是记录的只读分区集合,是Spark的基本数据结构。
RDD表明一个不可变、可分区、里面的元素可并行计算的集合。
通常有两种方式能够建立RDD,第一种是读取文件中的数据生成RDD,第二种则是经过将内存中的对象并行化获得RDD。
//经过读取文件生成RDD
val rdd = sc.textFile("hdfs://hans/data_warehouse/test/data")
//经过将内存中的对象并行化获得RDD
val num = Array(1,2,3,4,5)
val rdd = sc.parallelize(num)
//或者 val rdd = sc.makeRDD(num)
建立RDD以后,可使用各类操做对RDD进行编程。
RDD的操做有两种类型,即Transformation操做和Action操做。转换操做是从已经存在的RDD建立一个新的RDD,而行动操做是在RDD上进行计算后返回结果到 Driver。
Transformation操做都具备 Lazy 特性,即 Spark 不会马上进行实际的计算,只会记录执行的轨迹,只有触发Action操做的时候,它才会根据 DAG 图真正执行。
操做肯定了RDD之间的依赖关系。
RDD之间的依赖关系有两种类型,即窄依赖和宽依赖。窄依赖时,父RDD的分区和子RDD的分区的关系是一对一或者多对一的关系。而宽依赖时,父RDD的分区和子RDD的分区是一对多或者多对多的关系。
宽依赖关系相关的操做通常具备shuffle过程,即经过一个Patitioner函数将父RDD中每一个分区上key不一样的记录分发到不一样的子RDD分区。
依赖关系肯定了DAG切分红Stage的方式。
切割规则:从后往前,遇到宽依赖就切割Stage。
RDD之间的依赖关系造成一个DAG有向无环图,DAG会提交给DAGScheduler,DAGScheduler会把DAG划分红相互依赖的多个stage,划分stage的依据就是RDD之间的宽窄依赖。遇到宽依赖就划分stage,每一个stage包含一个或多个task任务。而后将这些task以taskSet的形式提交给TaskScheduler运行。
七,WordCount范例
只须要四行代码就能够完成WordCount词频统计。
val file = sc.textFile("hello.txt")
val word = file.flatMap(_.split(","))
val wordOne = word.map((_,1))
wordOne.reduceByKey(_+_)
本文主要来自厦门大学林子雨老师的《Spark编程基础》课程读书笔记,点击文末阅读原文查看课程连接。
本文分享自微信公众号 - Python与算法之美(Python_Ai_Road)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。