Spark是一种基于内存的快速、通用、可扩展的大数据分析计算引擎。
是在MR的基础上进行开发的,使用的是scala语言。
目录
Spark Shuffle 和 Hadoop Shuffle 区别
Spark on Hive 和 Hive on Spark 区别
Spark为什么比MR快
-
Spark基于内存,MR基于磁盘,频繁的磁盘IO会消耗大量的时间。
-
Spark排序不是必须的,MR无论结果是否需要都会进行排序。
-
Spark的任务是以线程的方式运行在进程中的,MR的任务是以进程的方式运行在Yarn集群中的,开启和调度进程的代价大于线程的代价。
Saprk运行流程
-
启动Drive,创建SparkContext
-
Client提交程序给Driver,Driver向集群Master申请资源创建Excutor
-
Master接收请求,分配资源发送给Driver
-
Driver按照资源分配方案连接集群worker,在worker中启动Excutor
-
SparkContext根据RDD算子的依赖创建DAG有向无环图
-
DAG Scheduler将DAG分解成Stage并发送给Task Scheduler
-
Excutor向SparkContext申请Task
-
Task Scheduler将Task发生给Excutor运行,同时SparkContext将应用程序代码发放给Excutor
-
Task 在Excutor上运行,运行完毕释放所有资源
RDD介绍
RDD,Resilient Distributed Dataset 弹性分布式数据集,是Spark中最基本的数据抽象,但是不存放数据。
在代码中是一个抽象类,类似ArrayList类,String类,它代表一个弹性、不可变、可区分、里面元素可以并行计算的集合。
为什么需要RDD?
RDD可以看做是一个分布式计算模型:
-
是一个对象(抽象类,类似String类)
-
封装了大量方法和属性(计算逻辑,不能太复杂,有通用性)
-
适合分布式处理(划分数据,实现并行计算)
RDD算子
- Transformations转换算子:实现功能的补充和封装,将就的RDD转换成新的RDD,如map,filter
- Action动作算子:触发任务的调度和作业的执行,如collect、sum
对于转换操作(Transformations),RDD的所有转换都不会直接计算结果。 Spark仅记录作用于RDD上的转换操作逻辑,当遇到动作算子( Action)时才会进行真正计算。
DAG有向无环图
在Saprk中,使用DAG来描述的计算逻辑。
-
整个计算任务称为Application
-
Application按照action算子(clooect、savAsTextFile)划分为多个Job(作业)
-
Job按照Shuffle算子(groupByKey)划分为多个Stage(阶段)
-
RDDstage之间会有依赖关系,后面根据前面的依赖关系来构建,如果前面的数据丢了, 它会记住前面的依赖,Spark可以通过这个依赖关系重新计算丢失的分区数据,⽽不是对RDD的所有分区进⾏重新计算。
-
-
Stage按照算子划分为Task(任务),Task是Spark运行的最小调度单元
Shuffle算子
使用shuffle的常见算子:join、groupByKey、reduceByKey、countByKey、...ByKey
-
窄依赖:RDD 之间分区是一一对应的
-
宽依赖:发生shuffle,多对多的关系,宽依赖表示子RDD的一个分区依赖了父RDD的多个分区
shuffle流程
Spark Shuffle分为两种:
-
基于Hash的Shuffle
在基于 Hash 的 Shuffle 实现方式中,每个 Mapper 阶段的 Task 会为每个 Reduce 阶段的 Task 生成一个文件,通常会产生大量的文件,伴随大量的随机磁盘 I/O 操作与大量的内存开销。
-
合并机制:倘若Executor只有一个core,所以每次只能有一个task执行,当第一个task执行完成后,第二个task会复用第一个task所创建的buffer和磁盘文件,从而减少磁盘文件的个数
-
基于Sort的Shuffle
在溢写磁盘前,先根据 key 进行排序,排序过后的数据,会分批写入到磁盘文件中。默认批次为 10000 条,数据会以每批一万条写入到磁盘文件。写入磁盘文件通过缓冲区溢写的方式,每次溢写都会产生一个磁盘文件,也就是说一个 Task 过程会产生多个临时文件。最后在每个 Task 中,将所有的临时文件合并,这就是 merge 过程,此过程将所有临时文件读取出来,一次写入到最终文件。
-
bypass运行机制:减少了小文件,不排序,效率高。在不需要排序的场景使用。
Spark Shuffle 和 Hadoop Shuffle 区别
-
Hadoop 不用等所有的 MapTask 都结束后开启 ReduceTask;Spark 必须等到父 Stage都完成,才能去 Fetch 数据。
-
Hadoop 的 Shuffle 是必须排序的,那么不管是 Map 的输出,还是 Reduce 的输出,都是分区内有序的,而 Spark 不要求这一点。
RDD五大特性
-
RDD由一系列分区partition组成;
-
对RDD计算相当于对RDD每个分区做计算(算⼦是作⽤在partition之上的);
-
RDD之间存在依赖关系;
-
分区器是作⽤在kv形式的RDD上;
-
尽量让计算程序靠近数据源,移动数据不如移动计算程序;计算每个分区时,在分区所在机器的本地上运行task是最好的,避免了数据的移动,减少数据的IO和网络传输,这样才能更好地减少作业运行时间。
RDD的弹性怎么体现
“弹性”指的是可以根据计算规模进行动态改变计算资源的特性。当计算量增长时,可以动态增加资源来满足计算需求,而当计算量减少时,又可以降低资源配置来节约成本。
-
存储弹性
Spark能够自动的进行内存和磁盘数据存储的切换,优先把数据放到内存中,如果内存实在放不下,会放到磁盘里面 -
计算弹性
基于Lineage血缘的高效容错,某个节点出错,可以从前一个节点恢复数据。 -
重试弹性,Task和Stage如果失败会自动进行特定次数的重试
-
Checkpoint检查点(每次对 RDD 操作都会产生新的 RDD,如果链条比较长,计算比较笨重,就把数据放在硬盘中)和persist持久化(内存或磁盘中对数据进行复用)
-
数据调度弹性,Spark将执行模型抽象为DAG,这可以将多Stage的任务串联或并行执行,从而不需要将Stage中间结果输出到HDFS中,当发生节点运行故障时,可有其他可用节点代替该故障节点运行。DAG Task 和资源管理无关。
-
数据分片弹性,Spark进行数据分片时,默认将数据放在内存中,如果内存放不下,一部分会放在磁盘上进行保存。 repartion
SparkSQL底层原理
-
将SQL语句转换成语法抽象树AST
-
生成逻辑计划,并对逻辑计划进行优化
-
生成物理计划
-
最后生成代码到集群中以为RDD的形式运行
对比HiveSQL的解析过程:
-
解析器:将SQL语句转换成语法抽象树AST
-
语义分析器:将语法抽象树进一步抽象为基本的查询单元:查询块QueryBlock
-
通过遍历查询块,生成逻辑计划,并对逻辑计划进行优化
-
根据优化后的逻辑计划生成物理计划(MR任务),并对物理计划进优化
-
执行器:执行物理计划(MR任务)