首页  

spark     所属分类 bigdata 浏览量 1436
基于内存的分布式计算框架

MapReduce缺点

1.调度慢,启动map、reduce太耗时
2.计算慢,每一步都要保存中间结果落磁盘
3.API抽象简单,只有map和reduce两个原语
4.缺乏作业流描述,一项任务需要多轮MR

spark特点

最大化利用内存cache
中间结果放内存,加速迭代
缓存结果集 ,加速后续处理 
更丰富的API(Transformation类和Actions类)
完整作业描述,将整个作业串起来 DAG
Excutor进程可以运行多个Task线程, 加快处理速度


select * from table where col1 > 50
rdd.registerastable(cachetable)
select col2, max (col3) from cachetable group by col2
select col3, max (col2) from cachetable group by col3

val file = sc.textFile(hdfs://input)
val counts = file.flatMap(
line => line.split(" "))
.map(word => (word, 1))
.reduceByKey(_ + _)
counts.saveAsTextFile(hdfs://output)


核心 RDD( Resilient Distributed Dataset)  弹性分布式数据集

1.四个特征
R显式将计算结果保存在内存中,控制数据的划分
记录数据的变换和描述,而不是数据本身,以保证容错
懒操作,延迟计算,action的时候才操作
瞬时性,用时才产生,用完就释放

2.四种构建方法
从共享文件系统中获取,如HDFS 
val a = sc.textFile("/xxx/yyy/file")

通过现有RDD转换得到
val b = a.map(x => (x, 1))

定义一个scala数组
val c = sc.parallelize(1 to 10, 1)

由一个已经存在的RDD通过持久化操作生成
val d = a.persist()
a. saveAsHadoopFile("/xxx/yyy/zzz")

3.partition和依赖

每个RDD包含了数据分块/分区(partition)的集合,每个partition是不可分割的
每个partition的计算就是一个task,task是调度的基本单位
与父RDD的依赖关系(rddA=>rddB)

宽依赖
B的每个partition依赖于A的所有partition
比如groupByKey reduceByKey join ,由A产生B时会先对A做shuffle

窄依赖 
B的每个partition依赖于A的常数个partition
map filter union 

窄依赖:表现为一个父RDD的分区对应于一个子RDD的分区或者多个父RDD的分区对应于一个子RDD的分区。
宽依赖:表现为存在一个父RDD的一个分区对应一个子RDD的多个分区。 

4.stage和依赖

从后往前,将宽依赖的边删掉,连通分量及其在原图中所有依赖的RDD,构成一个stage
每个stage内部尽可能多地包含一组具有窄依赖关系的转换,并将它们流水线并行化

5.数据局部性原则

如果一个任务需要的数据在某个节点的内存中,这个任务就会被分配至那个节点
需要的数据在某个节点的文件系统中,就分配至那个节点

6.容错性原则

如果此task失败,AM会重新分配task
如果task依赖的上层partition数据已经失效了,会先将其依赖的partition计算任务再重算一遍

宽依赖中被依赖partition,可以将数据保存HDFS,以便快速重建(checkpoint)
窄依赖只依赖上层一个partition,恢复代价较少
可以指定保存一个RDD的数据至节点的cache中,如果内存不够,会LRU释放一部分,仍有重建的可能


基本组件
Application:用户编写的Spark应用程序。
Driver:
Spark中的Driver即运行上述Application的main函数并创建SparkContext,
创建SparkContext的目的是为了准备Spark应用程序的运行环境,
在Spark中有SparkContext负责与ClusterManager通信,进行资源申请、任务的分配和监控等,
当Executor部分运行完毕后,Driver同时负责将SparkContext关闭。

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

Stage的划分

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

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


Cluter Manager:指的是在集群上获取资源的外部服务。目前有三种类型 
1) Standalon : spark原生的资源管理,由Master负责资源的分配 
2) Apache Mesos:与hadoop MR兼容性良好的一种资源调度框架 
3) Hadoop Yarn: 主要是指Yarn中的ResourceManager

一个Application由一个Driver和若干个Job构成,一个Job由多个Stage构成,一个Stage由多个没有Shuffle关系的Task组成。

当执行一个Application时,Driver会向集群管理器申请资源,启动Executor,
并向Executor发送应用程序代码和文件,然后在Executor上执行Task,
运行结束后,执行结果会返回给Driver,或者写到HDFS或者其它数据库中。

与Hadoop MapReduce计算框架相比,Spark所采用的Executor有两个优点:

利用多线程来执行具体的任务减少任务的启动开销;
Executor中有一个BlockManager存储模块,会将内存和磁盘共同作为存储设备,有效减少IO开销;

运行流程

为应用构建起基本的运行环境,即由Driver创建一个SparkContext进行资源的申请、任务的分配和监控
资源管理器为Executor分配资源,并启动Executor进程
SparkContext根据RDD的依赖关系构建DAG图,DAG图提交给DAGScheduler解析成Stage,然后把一个个TaskSet提交给底层调度器TaskScheduler处理。 
Executor向SparkContext申请Task,TaskScheduler将Task发放给Executor运行并提供应用程序代码。
Task在Executor上运行把执行结果反馈给TaskScheduler,然后反馈给DAGScheduler,运行完毕后写入数据并释放所有资源。


运行机制特点

每个Application都有自己专属的Executor进程,并且该进程在Application运行期间一直驻留。Executor进程以多线程的方式运行Task。
Spark运行过程与资源管理器无关,只要能够获取Executor进程并保存通信即可。
Task采用数据本地性和推测执行等优化机制。




Spark技术栈 

Spark Core   基于RDD提供操作接口 
Spark SQL   sql转化为DAG 
Spark Streaming    流式计算框架 minibatch 
MLIB  机器学习库 
GraphX 图计算

上一篇     下一篇
zab协议

hive

HIVE数据模型

5G简介

git pull --rebase 使用

中概互联50ETF