概述
RDD 介绍
RDD 弹性分布式数据集
弹性:具有容错性,在节点故障导致丢失或者分区损坏,可以进行重新计算数据
分布式: 数据分布式存储,分布式计算(分布式执行)
数据集:传统意义上的数据集,不过这个数据集不是真实存在的,只是一个代理,正真数据集的获取 需要通过Task来或者
RDD 真正意义上不存储数据,只是代理,任务代理,对RDD的每次操作都会根据Task的类型转换成Task进行执行
Spark中关于RDD的介绍:
1. 分区列表(分区有编号,分区中包含的切片迭代器)
2. 提供了切片的计算入口函数(RDD具有一些列的函数(Trans/Action))
3. 其他RDD的一系列依赖(一个RDD 可以依赖于其他RDD)
4. (可选) 分区RDD (一个RDD也可以是一个分区RDD,可以对分区RDD进行处理)
5. (可选) 对RDD提供了一系列的计算函数 (RDD提供了对一些了切片的首选执行方法)
RDD 有俩类函数,transformations (懒加载)/Action(立即执行)
transformations 与Action最明显的区别在于:
1. transformations 为懒函数,action是实时函数
2. transformations 执行完毕后任然为RDD ,但是Action 执行完毕为 scala数据类型。
transformations函数为懒加载函数,调用该函数时函数不会立即执行,只记录函数执行操作,相当于pipeline,只是定义了RDD的执行过程,只有当Action函数出发以后,才会调用前面的Transformation。
Action函数为实时函数,执行了就会通过Master下发Task任务到Worker端,执行相应的处理。
transformations类函数:此类函数只会记录RDD执行逻辑,并不正真下发任务执行数据处理
函数列表:
flatmap,union,intersection,join,groupby,filter,
reducebykey,map,mappatation,mappartitionindex,
reducebykey,aggregatebykey
Action类函数:此类函数会正真的执行Task任务,调用Worker端执行Executor 任务。
函数列表:
collect,partition,take,first,reduce,takeordered,top,
count,mappartitionindex,aggregate,saveastextfile,
foreach,foreachpatation
spark-shell : Spark 的交互式客户端,启动那一刻就开始执行任务,一般不用这种执行方式。
Spark与MapReduce缘何比MapReduce快几十倍甚至上百倍
MapReduce的执行逻辑
MapReduce有Map任务和Reduce任务组成,执行流程为: Map->(Shuffle)->Reduce,如果有多次的数据处理,会涉及到多次的Map->(Shuffle)->Reduce 执行。
假设一个计算涉及四步,则实现流程为:
(1)Map->(Shuffle)->Reduce -> HDFS/HBase/Hive #第一个MR任务,开始调度,执行数据
(2)Map->(Shuffle)->Reduce -> HDFS/HBase/Hive #第二个MR任务,开始调度,执行数据
(3)Map->(Shuffle)->Reduce -> HDFS/HBase/Hive #第三个MR任务,开始调度,执行数据
(4)Map->(Shuffle)->Reduce -> HDFS/HBase/Hive #第四个MR任务,开始调度,执行数据
以上 各个MR任务都是顺序执行,不能并行处理,并且每个MR任务都有Shuffle操作,其实Shuffle操作是记录中间数据到HDFS文件目录中,所以每个MR任务都涉及读写文件操作,大大降低了执行效率。
Spark的执行逻辑:
Spark执行操作是通过RDD进行管理的,RDD保存的不是真实数据,而是一个任务代理,里面记录了数据的执行逻辑,类似PipeLine;并且RDD在执行过程中产生的中间数据如果数据量小的话,是保存在内存中的,数据量大了以后也会保存近文件,这个RDD会自行判断处理。
同样我们假设 Spark的一个计算也设计四步,则执行流程为:
(1) RDD1 [PartitonRDD] FromTextFile #此RDD为Transformation类型,从HDFS中读取文件,此时RDD1中保存的展示文件的一个代理信息,包括分区信息
(2) RDD2 [StringRDD] FlatMap #此RDD为Transformation类型,从文件中读取每一行,进行处理,此时RDD2保存的仍然是一个代理信息,并没有具体的数据
(3) RDD3 [StringRDD] Reduce #此RDD为Transformation类型,收集RDD2的单行信息,进行汇总,此时RDD3保存的仍然是一个代理信息,并没有具体的数据
(4) RDD3 [StringRDD] Collect/Count/SaveToText File #此RDD为Action类型,该RDD会记录上面所有的RDD操作,然后通过HMaster下发任务到Worker端,进行相应的任务执行,最后保存数据到HDFS
以上前三个RDD只记录操作逻辑,不执行具体操作,并且没有中间缓存数据,第四个RDD才真正下发任务执行任务处理,相对来说数据处理更加精细化,流程可控,编写简单。
综上所述,MapReduce与Spark的明显区别在于:
1. MapReduce 计算流程会执行多次,而Spark只会执行一次
2. MapReduce 的中间数据都会保存在文件,而Spark中间数据在内存中,处理起来会更加快。
3. MapReduce 所有的计算逻辑都的用户自己实现,效率层次不齐,而Spark提供了100多个Transpotaton/Action 算子,执行效率会比用户要好,如果用户可以写出更好的,此条可以或略不记。
自定义分区:
Spark在执行过程中可以对分区进行自定义,默认启动俩个分区,如果执行的数据块有三个或者更多,会根据文件个数及大小自动扩展分区个数,之所以讲分区是因为在后面执行Action操作的时候,会根据分区个数自动分配Task任务,一般分区个数会与Task任务个数向匹配。如果Worker端不能同时执行那么多的Task任务时,会分批次进行执行,当前Task任务执行完毕才能执行下一批次Task任务。比如Spark集群存在5个worker,每个worker可以通知执行2个Executor,那该集群可同时执行10个Task任务,如果发送过来50个Task任务,则会分5批执行完这50个Task任务。
Spark任务执行的多种方式及需要规避的策略 :
1. 每个计算操作都可以有多种方式执行,多种方式的前提是结果一直。但是方式不同,执行的效率大不一样。
2. 对每个计算操作,在编写Spark之前,最好在纸上规划一下,计划那些算在在Worker端处理,那些汇总处理,竟可能保证计算的高效性和正确性,减少数据的网络传输。
3. 一般来将,对于小数据来,可以在SparkSubmit(Driver) 对数据进行汇总操作,比如Count;对于大数据是万万不能的,因为返回的数据可能是海量数据,全部放在Driver端导致Driver端不能处理而崩溃(数据量太大,直接导致内存/CPU等报错),建议是尽量在Worker端进行数据汇总后在返回给Driver端
4. 在做Spark计算时,最好有一个比较好的分区策略,让数据流按着自己的思路进行分区计算或者保存,这样子就尽量避免了后面在数据计算时数据在Worker间的传输所产生的性能消耗和网络负载。同样对于小批量数据可以没那么严格要求,对于海量数据,分区所产生的性能消耗也是非常客观的,所以在编写海量数据的算子时,对分区的自定义还是有必要的。
5. 部署Spark计算框架时,最好是Worker节点同HDFS的DataNode节点保持在同一台主机上,这样就可以尽可能的减少数据在网络间的传输,并且数据相对来说在本地的话,读取效率也会有所提升。
6. 最后重点强调:编写Spark算子需要具备分布式思维,不能用本地文件系统思维处理分布式文件。
最后
以上就是合适心锁为你收集整理的Spark RDD 整体介绍的全部内容,希望文章能够帮你解决Spark RDD 整体介绍所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复