Spark核心之06:知识点梳理
spark知识点梳理
spark_〇一
1、spark是什么
spark是针对于大规模数据处理的统一分析引擎,它是基于内存计算框架,计算速度非常之快,但是它仅仅只是涉及到计算,并没有涉及到数据的存储,后期需要使用spark对接外部的数据源,比如hdfs。
2、spark四大特性
-
1、速度快
-
spark比mapreduce快的2个主要原因
-
1、基于内存
(1)mapreduce任务后期再计算的时候,每一个job的输出结果会落地到磁盘,后续有其他的job需要依赖于前面job的输出结果,这个时候就需要进行大量的磁盘io操作。性能就比较低。 (2)spark任务后期再计算的时候,job的输出结果可以保存在内存中,后续有其他的job需要依赖于前面job的输出结果,这个时候就直接从内存中获取得到,避免了磁盘io操作,性能比较高 对于spark程序和mapreduce程序都会产生shuffle阶段,在shuffle阶段中它们产生的数据都会落地到磁盘。
-
2、、进程与线程
(1)mapreduce任务以进程的方式运行在yarn集群中,比如程序中有100个MapTask,一个task就需要一个进程,这些task要运行就需要开启100个进程。 (2)spark任务以线程的方式运行在进程中,比如程序中有100个MapTask,后期一个task就对应一个线程,这里就不在是进程,这些task需要运行,这里可以极端一点: 只需要开启1个进程,在这个进程中启动100个线程就可以了。 进程中可以启动很多个线程,而开启一个进程与开启一个线程需要的时间和调度代价是不一样。 开启一个进程需要的时间远远大于开启一个线程。
-
-
-
2、易用性
可以快速去编写spark程序通过 java/scala/python/R/SQL等不同语言
-
3、通用性
spark框架不在是一个简单的框架,可以把spark理解成一个==生态系统==,它内部是包含了很多模块,基于不同的应用场景可以选择对应的模块去使用
- sparksql
- 通过sql去开发spark程序做一些离线分析
- sparkStreaming
- 主要是用来解决公司有实时计算的这种场景
- Mlib
- 它封装了一些机器学习的算法库
- Graphx
- 图计算
- sparksql
-
4、兼容性
- spark程序就是一个计算逻辑程序,这个任务要运行就需要计算资源(内存、cpu、磁盘),哪里可以给当前这个任务提供计算资源,就可以把spark程序提交到哪里去运行
- standAlone(后期使用较多)
- 它是spark自带的独立运行模式,整个任务的资源分配由spark集群的老大Master负责
- yarn(后期使用较多)
- 可以把spark程序提交到yarn中运行,整个任务的资源分配由yarn中的老大ResourceManager负责
- mesos
- 它也是apache开源的一个类似于yarn的资源调度平台
- standAlone(后期使用较多)
- spark程序就是一个计算逻辑程序,这个任务要运行就需要计算资源(内存、cpu、磁盘),哪里可以给当前这个任务提供计算资源,就可以把spark程序提交到哪里去运行
3、spark集群的架构
- 理解spark中这些角色和概念
- Driver端
- Application
- Master
- Worker
- Executor
- task
4、spark集群安装部署
5、spark-shell(★★★★★)
- spark-shell --master local[N]
- spark-shell --master spark://node01:7077
6、通过IDEA开发工具开发spark程序(★★★★★)
- scala语言开发
- 本地运行
- 设置master地址是local
- 集群运行
- 把程序打成jar包提交到集群中运行
- 设置master地址是集群中的master
- 把程序打成jar包提交到集群中运行
- 本地运行
- java语言开发
本次课可能会涉及到的面试题
(1) 简述spark与mapreduce的区别?
(2) 简单聊聊spark处理速度为什么比mapreduce要快?
(3) 简述搭建一个spark集群的步骤?
(4) 用 java/scala/python/shell 中的一种语言来实现基于一个文件的单词统计程序?
spark_〇二
1、rdd的概念
- RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合.
2、rdd的五大属性(★★★★★)
-
(1)A list of partitions
- 一个分区(Partition)列表,数据集的基本组成单位。
-
(2)A function for computing each split
- 一个计算每个分区的函数
-
(3)A list of dependencies on other RDDs
- 一个rdd会依赖于其他多个rdd
- 通过lineage血统记录下rdd与rdd之间的依赖关系
- 好处
- 就在于后期某个rdd的部分分区数据丢失的时候,可以通过血统进行重新计算恢复得到
- 这也是spark任务自身的一个容错机制
- 一个rdd会依赖于其他多个rdd
-
(4)Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)
- (可选项)一个Partitioner,即RDD的分区函数
-
(5)Optionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file)
- 一个列表,存储每个Partition的优先位置(可选项)
3、rdd的创建方式
-
1、通过已经存在的scala集合去构建
val rdd1=sc.parallelize(List(1,2,3,4,5)) val rdd2=sc.parallelize(Array("hadoop","hive","spark")) val rdd3=sc.makeRDD(List(1,2,3,4))
-
2、加载外部的数据源去构建
val rdd1=sc.textFile("/words.txt")
-
3、从已经存在的rdd进行转换生成一个新的rdd
val rdd2=rdd1.flatMap(_.split(" ")) val rdd3=rdd2.map((_,1))
4、rdd的算子操作分类
-
1、transformation(转换)
- 根据已经存在的rdd转换生成一个新的rdd, 它是延迟加载,它不会立即执行
- 例如
- map / flatMap / reduceByKey 等
-
2、action (动作)
-
它会真正触发任务的运行
- 将rdd的计算的结果数据返回给Driver端,或者是保存结果数据到外部存储介质中
-
例如
- collect / saveAsTextFile 等
-
5、RDD常见的算子操作说明(★★★★★)
- 重点需要掌握
- map / mapPartitions / foreach / foreachPartition算子区别操作?
map:用于遍历RDD,将函数f应用于每一个元素,返回新的RDD(transformation算子)。
mapPartitions:用于遍历操作RDD中的每一个分区,返回生成一个新的RDD(transformation算子)。
总结:
如果在映射的过程中需要频繁创建额外的对象,使用mapPartitions要比map高效
比如,将RDD中的所有数据通过JDBC连接写入数据库,如果使用map函数,可能要为每一个元素都创建一个connection,这样开销很大,如果使用mapPartitions,那么只需要针对每一个分区建立一个connection。
foreach:用于遍历RDD,将函数f应用于每一个元素,无返回值(action算子)。
foreachPartition: 用于遍历操作RDD中的每一个分区。无返回值(action算子)。
总结:
一般使用mapPartitions或者foreachPartition算子比map和foreach更加高效,推荐使用。
- coalesce/ repartition 算子区别操作
repartition: 重新分区, 有shuffle
coalesce: 合并分区/减少分区 默认不shuffle
//默认 coalesce 不能扩大分区数量。除非添加true的参数,或者使用repartition。
repartition(numPartitions)其本质是调用了coalesce(numPartitions,true)方法,第二个参数默认是true,表示会产生shuffle。
//适用场景:
//1、如果要shuffle,都用 repartition
//2、不需要shuffle,仅仅是做分区的合并,coalesce
//3、repartition常用于扩大分区。
本次可能会涉及到的面试题
(1)简单聊聊spark中的RDD是什么,有啥特性
(2)说一下rdd的算子操作map、mapPartitions、foreach、foreachPartition的区别
(3)简述rdd的算子操作coalesce、repartition的区别
spark_〇三
1、RDD的算子操作案例(★★★★★)
- 重点掌握rdd常见的一些算子操作
- flatMap
- map
- reduceByKey
- sortBy
- distinct
- count
- mapPartitions
- foreach
- foreachPartition
2、RDD的依赖关系
-
窄依赖
哪些算子操作是窄依赖: map/flatMap/filter/union/join等等 所有的窄依赖不会产生shuffle
-
宽依赖
哪些算子操作是宽依赖: reduceByKey/sortByKey/groupBy/groupByKey/join等等 所有的宽依赖会产生shuffle
3、RDD的缓存机制(★★★★★)
- 1、什么是rdd的缓存机制、好处是什么?
- 2、如何对rdd设置缓存? cache和persist方法的区别是什么?
- 3、什么时候设置缓存?
- 4、如何清除缓存?
val rdd2=rdd1.map(xxxx).reduceBykey(xxxx)
rdd2.map(xxxx).saveAsTextFile("目录1")
rdd2.groupByKey(xxxx).saveAsTextFile("目录2")
4、RDD的checkpoint机制(★★★★★)
- 1、rdd的checkpoint是什么
- 2、如何对rdd进行checkpoint操作
5、DAG有向无环图
- 1、DAG有向无环图是什么,如何生成的?
6、如何进行stage划分(★★★★★)
- 1、stage是什么
- 2、为什么要划分stage
- 3、如何划分stage
- 4、stage与stage之间的关系
本次可能会涉及到的面试题
(1)、reduceByKey和groupByKey的区别是什么?
(2)、下面哪些操作是宽依赖?
flatMap、map 、filter、reduceByKey
(3)、简述cache和persist方法的区别?
(4)、简述如何划分stage?
spark_〇四
1、spark任务的划分、提交、调度流程(★★★★★)
- 详细见课件描述
- 自己能动手边说边画图
2、spark中自定义分区
-
默认是HashPartitioner
-
该函数对key进行哈希,然后对分区总数取模,取模结果相同的就会被分到同一个partition中
HashPartitioner分区逻辑: key.hashcode % 分区总数 = 分区号
-
如果嫌HashPartitioner功能单一,可以自定义partitioner
-
3、spark中的共享变量
-
广播变量(★★★★★)
- 广播变量是什么?
- 广播变量的原理?
- 广播变量如何使用? 不使用可不可以,使用之后达到什么效果?
-
累加器
- 分布式改变、然后聚合这些改变。
4、spark程序的序列化问题(★★★★★)
- 常见的一些序列化问题
- 如何解决spark程序中的序列化问题
本次可能会涉及到的面试题
(1)简述spark任务的提交、划分、调度流程?
(2)spark程序进行过什么优化?
广播变量就是其中的一个优化点。
(3)spark程序有没有遇到过序列化的问题,如何解决的?
spark_〇五
1、spark on yarn 原理机制(★★★★★)
-
yarn-cluster模式
- spark程序的Driver程序在YARN中运行,运行结果不能在客户端显示,并且客户端可以在启动应用程序后消失应用的。
-
yarn-client模式
- spark程序的Driver运行在Client上,应用程序运行结果会在客户端显示,所有适合运行结果有输出的应用程序(如spark-shell)
-
总结
yarn-cluster: Driver端运行在yarn集群中,与ApplicationMaster进程在一起。 yarn-client: Driver端运行在提交任务的客户端,与ApplicationMaster进程没关系,经 常用于进行测试
2、collect 算子操作剖析
-
作用
- 1、它是一个action操作,会触发任务的运行
- 2、它会把RDD的数据进行收集之后,以数组的形式返回给Driver端
- 总结:
-
默认Driver端的内存大小为1G,由参数 spark.driver.memory 设置
-
如果某个rdd的数据量超过了Driver端默认的1G内存,对rdd调用collect操作,这里会出现Driver端的内存溢出,所有这个collect操作存在一定的风险,实际开发代码一般不会使用。
-
实际企业中一般都会把该参数调大,比如5G/10G等
- 可以在代码中修改该参数,如下
new SparkConf().set("spark.driver.memory","5G")
-
3、spark中计算资源的参数说明(★★★★★)
-
–executor-memory
- 表示每一个executor进程需要的内存大小,它决定了后期操作数据的速度
-
–total-executor-cores
- 表示任务运行需要总的cpu核数,它决定了任务并行运行的粒度
-
总结
后期对于spark程序的优化,可以从这2个参数入手,无论你把哪一个参数调大,对程序运行的效率来说都会达到一定程度的提升 加大计算资源它是最直接、最有效果的优化手段。 在计算资源有限的情况下,可以考虑其他方面,比如说代码层面,JVM层面等
4、spark任务的调度模式
- Spark中的调度模式主要有两种:FIFO 和 FAIR
5、 spark任务的分配资源策略
- 尽量打散
- 在分配计算资源的时候,尽可能让更多的worker节点参与计算任务
- 它是默认选项,可以充分的发挥数据的本地性,提升执行效率
- 在分配计算资源的时候,尽可能让更多的worker节点参与计算任务
- 尽量集中
- 在分配计算资源的时候,尽可能让更少的worker节点参与计算任务
6、 spark的shuffle原理分析(★★★★★)
-
HashShuffle
- HashShuffleManager的运行机制主要分成两种
- 一种是普通运行机制
- 另一种是合并的运行机制。
- 合并机制主要是通过复用buffer来优化Shuffle过程中产生的小文件的数量。
- Hash shuffle是不具有排序的Shuffle。
- HashShuffleManager的运行机制主要分成两种
-
SortShuffle
- SortShuffleManager的运行机制主要分成两种
- 一种是普通运行机制
- 另一种是bypass运行机制 (没有排序的SortShuffle)
- 在shuffleMapTask数量小于默认值200时,启用bypass模式的sortShuffle
- SortShuffleManager的运行机制主要分成两种