1.什么是Spark
spark是一种基于内存的快速、通用、可扩展的大数据分析引擎,基于内存的计算框架
2.spark的生态?
spark core: Spark 的核心 实现了Spark的基本功能,包含任务调度、内存管理、错误恢复、与存储系统交互等模块。
spark sql: 使用sql对历史数据做交互式查询,用来操作结构化数据
spark Streaming: 近实时计算 对实时数据进行流式计算的组件
spark graphx: 图计算 关注事物本身和事物之间的联系
spark mllib: 机器学习 包括分类、回归、聚类、协同过滤等,还提供了模型评估、数据 导入等额外的支持功能
3.即席查询: 用户根据需求自定义查询
4.实时计算框架? storm spark Streaming flink
5.spark 的资源管理器?
Spark支持在各种集群管理器(Cluster Manager)上运行,包括Hadoop YARN、Apache Mesos,以及Spark自带的一个简易调度 器,叫作独立调度器。 standalone
6.spark 比 mr 快的原因?
基于内存 DAG执行引擎 cache
7.spark的部署模式?
Local本地模式
yarn模式
Standalone模式
8.submit的参数有哪些?
--master master 的地址,提交任务到哪里执行,例如 spark://host:port, yarn, local
--deploy-mode 在本地 (client) 启动 driver 或在 cluster 上启动,默认是 client
--class 应用程序的主类,仅针对 java 或 scala 应用
--name 应用程序的名称
--jars 用逗号分隔的本地 jar 包,设置后,这些 jar 将包含在 driver 和 executor 的 classpath 下
--packages 包含在driver 和executor 的 classpath 中的 jar 的 maven 坐标
--exclude-packages 为了避免冲突 而指定不包含的 package
--repositories 远程 repository
--properties-file 加载的配置文件,默认为 conf/spark-defaults.conf
--driver-memory Driver内存,默认 1G
--driver-java-options 传给 driver 的额外的 Java 选项
--driver-library-path 传给 driver 的额外的库路径
--driver-class-path 传给 driver 的额外的类路径
--driver-cores Driver 的核数,默认是1。在 yarn 或者 standalone 下使用
--executor-memory 每个 executor 的内存,默认是1G
--total-executor-cores 所有 executor 总共的核数。仅仅在 mesos 或者 standalone 下使用
--num-executors 启动的 executor 数量。默认为2。在 yarn 下使用
--executor-core 每个 executor 的核数。在yarn或者standalone下使用
9.画出spark提交流程?
10.Driver(驱动器)的作用?
1.把用户程序转为作业(JOB)
2.跟踪Executor的运行状况
3.为执行器节点调度任务
4.UI展示应用运行状况
11.Executor(执行器)的作用?
1.负责运行组成 Spark 应用的任务,并将结果返回给驱动器进程;
2.通过自身的块管理器(Block Manager)为用户程序中要求缓存的RDD提供内存式存储。RDD是直接缓存在Executor进程内的,因此任务可以在运行时充分利用缓存数据加速运算。
12.Spark的特点?
快 :spark实现了高效的DAG执行引擎,可以通过基于内存来高效处理数据流
易用:spark支持Java、Python和scala的API,还支持超过80种高级算法,使用户可以快速构建不同的应用
通用:spark提供了统一的解决方案。可以用于批处理、交互式查询(spark SQL)、实时流处理(spark streaming)
、机器学习(spark MLlib)和图计算(Graphx)
兼容性:spark可以非常方便地与其他的开源产品进行融合
13.spark的提交方式? client(克兰n它) cluster(可拉s它) 区别?
spark的提交的方式是client还是 cluster
区别主要是在于driver在哪里运行:client
在当前提交的节点运行,cluster 在集群的某一个节点
client 下没有监督重启机制,Driver进程如果挂了,需要额外的程序重启
yarn client模式:driverzai当前提交任务的节点上,可以打印任务运行的日志信息,而
yarn cluster模式:driver在AppMaster所有节点上,分布式分配,不能再提交任务的本机打印日志信息
14.spark能代替hadoop 吗?
1、不能,仅仅是mr的替代方案
2、spark会替代Hadoop的一部分,会替代Hadoop的计算框架,如mapReduce、Hive查询引擎,
但spark本身不提供存储,所以spark不能完全替代Hadoop
---------------------------------------------------------
15.什么是RDD?
RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象。代码中是一个抽象类,它代表一个不可变、可分区、里面的元素可并行计算的集合。
16. RDD的属性
1)一组分区(Partition),即数据集的基本组成单位;
2)一个计算每个分区的函数; spark 的算子
3)RDD之间的依赖关系;
4)一个Partitioner,即RDD的分片函数;
5)一个列表,存储存取每个Partition的优先位置(preferred location)。
17.RDD特点
RDD表示只读的分区的数据集,对RDD进行改动,只能通过RDD的转换操作,由一个RDD得到一个新的RDD,新的RDD包含了从其他RDD衍生所必需的信息。RDDs之间存在依赖,RDD的执行是按照血缘关系延时计算的。如果血缘关系较长,可以通过持久化RDD来切断血缘关系。
18.rdd的分区个数由什么决定? 默认 cpu的核数有关) 指定 从hdfs跟切片个数有关 从kafka获取数据跟topic的分区个数有关
19.RDD的操作算子包括两类?区别?
RDD的操作算子包括两类,
一类叫做transformations,它是用来将RDD进行转化,构建RDD的血缘关系;
另一类叫做actions,它是用来触发RDD的计算,得到RDD的相关计算结果或者将RDD保存的文件系统中。
transformations,会形成新的rdd
actions在rdd本身计算
20.rdd之间的依赖关系?分别是什么?
依赖包括两种,一种是窄依赖,RDD之间分区是一一对应的,另一种是宽依赖,下游RDD的每个分区与上游 RDD(也称之为父RDD)的每个分区都有关,是多对多的关系。
21.spark的容错方式?区别? lineage cp
lineage,重新计算
checkpoint,在挂掉的地方开始,避免重新计算
Lineage:RDD的Lineage会记录RDD的元数据信息和转换行为,
当该RDD的部分分区数据丢失时,它可以根据这些信息来重新运算和恢复丢失的数据分区。
checkpoint的意思就是建立检查点,checkpoint的作用就是将DAG中比较重要的中间数据做
一个检查点将结果存储到一个高可用的地方(通常这个地方就是HDFS里面).
22.缓存 和 checkpoint的区别?
缓存是为了多次复用rdd重计算,checkpoint防止节点挂掉导致数据丢失
23.在Spark中RDD的创建方式可以分为三种
在Spark中RDD的创建方式可以分为三种:从集合中创建RDD;从外部存储创建RDD;从其他RDD创建。
24.总结spark算子 30个
map(funt):返回一个新的RDD,该RDD由每一个输入元素经过func函数转换后组成
mapPartitions(func):类似于map,但独立地在RDD的每一个分片上运行,因此在类型为T的RDD上运行时,func的函数类型必须是Iterator[T] => Iterator[U]。一个函数一次处理所有分区。
mapPartitionsWithIndex(func):类似于mapPartitions,但func带有一个整数参数表示分片的索引值,因此在类型为T的RDD上运行时,func的函数类型必须是(Int, Interator[T]) => Iterator[U];
flatMap(func):类似于map,但是每一个输入元素可以被映射为0或多个输出元素(所以func应该返回一个序列,而不是单一元素)
glom():将每一个分区形成一个数组,形成新的RDD类型时RDD[Array[T]]
groupBy(func):分组,按照传入函数的返回值进行分组。将相同的key对应的值放入一个迭代器。
filter(func):过滤。返回一个新的RDD,该RDD由经过func函数计算后返回值为true的输入元素组成
sample(withReplacement, fraction, seed):以指定的随机种子随机抽样出数量为fraction的数据,withReplacement表示是抽出的数据是否放回,true为有放回的抽样,false为无放回的抽样,seed用于指定随机数生成器种子。
distinct([numTasks])):对源RDD进行去重后返回一个新的RDD。默认情况下,只有8个并行任务来操作,但是可以传入一个可选的numTasks参数改变它。
coalesce(numPartitions):缩减分区数,用于大数据集过滤后,提高小数据集的执行效率。
repartition(numPartitions):根据分区数,重新通过网络随机洗牌所有数据。
sortBy(func,[ascending], [numTasks]):使用func先对数据进行处理,按照处理后的数据比较结果排序,默认为正序。
pipe(command, [envVars]):管道,针对每个分区,都执行一个shell脚本,返回输出的RDD。
union(otherDataset): 并集 对源RDD和参数RDD求并集后返回一个新的RDD
subtract (otherDataset):差集 计算差的一种函数,去除两个RDD中相同的元素,不同的RDD将保留下来
intersection(otherDataset):交集 对源RDD和参数RDD求交集后返回一个新的RDD
cartesian(otherDataset):笛卡尔积(尽量避免使用)
zip(otherDataset):拉链 将两个RDD组合成Key/Value形式的RDD,这里默认两个RDD的partition数量以及元素数量都相同,否则会抛出异常。
partitionBy:对pairRDD进行分区操作,如果原有的partionRDD和现有的partionRDD是一致的话就不进行分区,?否则会生成ShuffleRDD,即会产生shuffle过程。
groupByKey:groupByKey也是对每个key进行操作,但只生成一个sequence。
reduceByKey(func, [numTasks]):在一个(K,V)的RDD上调用,返回一个(K,V)的RDD,使用指定的reduce函数,将相同key的值聚合到一起,reduce任务的个数可以通过第二个可选的参数来设置。
aggregateByKey:在kv对的RDD中,按key将value进行分组合并,合并时,将每个value和初始值作为seq函数的参数,进行计算,返回的结果作为一个新的kv对,然后再将结果按照key进行合并,最后将每个分组的value传递给combine函数进行计算(先将前两个value进行计算,将返回结果和下一个value传给combine函数,以此类推),将key与计算结果作为一个新的kv对输出。
foldByKey:aggregateByKey的简化操作,seqop和combop相同
combineByKey[C]:对相同K,把V合并成一个集合
sortByKey([ascending], [numTasks]):在一个(K,V)的RDD上调用,K必须实现Ordered接口,返回一个按照key进行排序的(K,V)的RDD
mapValues:针对于(K,V)形式的类型只对V进行操作
join(otherDataset, [numTasks]):在类型为(K,V)和(K,W)的RDD上调用,返回一个相同key对应的所有元素对在一起的(K,(V,W))的RDD
cogroup(otherDataset, [numTasks]):在类型为(K,V)和(K,W)的RDD上调用,返回一个(K,(Iterable
25. map()和mapPartition()的区别
map:每次处理一条数据
mapPartition: 每次处理一个分区的数据,这个分区的数据处理完后,原RDD
中分区的数据才能释放 可能导致OMM
当内存空间较大的时候建议使用mapPartition,以提高处理效率
26.spark 重分区算子? 区别场景?
coalesce 重新分区,可以选择是否进行shuffle过程。由参数shuffle: Boolean = false/true决定
repartition 实际上是调用的coalesce,默认是进行shuffle的。
场景:减少/合并分区优先使用coalesce 增大、提高分区使用repartition
27.reduceByKey和groupByKey的区别
reduceByKey:分组聚合
groupby:只分组
28.宽依赖算子? 所有bykey算子 部分join算子 笛卡尔积和repartition
29.什么是DAG?
DAG(Directed Acyclic Graph)叫做有向无环图,原始的RDD通过一系列的转换就就形成了DAG,根据RDD之间的依赖关系的不同将 DAG划分成不同的Stage,对于窄依赖,partition的转换处理在Stage中完成计算。
对于宽依赖,由于有Shuffle的存在,只能在parent RDD处理完成后,才能开始接下来的计算,因此宽依赖是划分Stage的依据。
30.如何划分stage?
根据RDD之间的依赖关系的不同将Job划分成不同的Stage,遇到一个宽依赖则划分一个Stage。
31.spark缓存?区别?
persist方法或cache方法
cache只有一个默认的缓存级别MEMORY_ONLY ,而persist可以根据情况设置其它的缓存级别。
32.持久化的级别? 如何选择?
内存 磁盘 序列化 副本
先选择MEMORY_ONLY(内存),如果MEMORY_ONLY放不下可以考虑MEMORY_ONLY_SER(序列化),
因为序列化过后占用的内存更小,如果序列化过后还放不下,那么就考虑MEMORY_AND_DISK(内存和磁盘),不到万不得已不使用 DISK_ONLY(磁盘),放在磁盘会影响性能
33.Spark目前支持分区? 区别?
hash分区:HashPartitioner,根据key的hash值与分区个数取余来进行分区,分区弊端:可能导致每个分区中数据量的不均匀,极端 情况下会导致某些分区拥有RDD的全部数据。
Ranger分区:RangePartitioner,将一定范围内的数映射到某一个分区内,尽量保证每个分区中数据量的均匀。类似与Hbase中的region
自定义分区:要实现自定义的分区器,你需要继承
34.spark的共享变量?
累加器 广播变量
35.手写Spark WC
def main(args: Array[String]): Unit = {
//屏蔽日志
Logger.getLogger("org").setLevel(Level.ERROR)
//local
val conf = new SparkConf().setAppName(this.getClass.getSimpleName)
val sc = new SparkContext(conf)
sc.textFile("F://大数据/input/clean.txt").flatMap(_.split("\t")).map((_,1)).reduceByKey(_+_).foreach(println(_))
36.画出 spark 执行流程图详解
37.master 资源分配算法?
有两种策略,尽量打散:尽量让需要的资源平均在不同的机器上启动,
还有以后一种策略是尽量集中,尽量在某一台或者几台机器上启动
38.总结spark Shuffle?
spark的shuffle分为两种实现,分别为HashShuffle和SortShuffle,
HashShuffle又分为普通机制和合并机制,普通机制因为其会产生M*R个数的巨量磁盘小文件而产生大量性能低下的Io操作,从而性能较低,因为其巨量的磁盘小文件还可能导致OOM,HashShuffle的合并机制通过重复利用buffer从而将磁盘小文件的数量降低到Core*R个,但是当Reducer 端的并行任务或者是数据分片过多的时候,依然会产生大量的磁盘小文件。
SortShuffle也分为普通机制和bypass机制,普通机制在内存数据结构(默认为5M)完成排序,会产生2M个磁盘小文件。而当shuffle map task数量小于spark.shuffle.sort.bypassMergeThreshold参数的值。或者算子不是聚合类的shuffle算子(比如reduceByKey)的时候会触发SortShuffle的bypass机制,SortShuffle的bypass机制不会进行排序,极大的提高了其性能
在Spark 1.2以前,默认的shuffle计算引擎是HashShuffleManager,因为HashShuffleManager会产生大量的磁盘小文件而性能低下,在Spark 1.2以后的版本中,默认的ShuffleManager改成了SortShuffleManager。SortShuffleManager相较于HashShuffleManager来说,有了一定的改进。主要就在于,每个Task在进行shuffle操作时,虽然也会产生较多的临时磁盘文件,但是最后会将所有的临时文件合并(merge)成一个磁盘文件,因此每个Task就只有一个磁盘文件。在下一个stage的shuffle read task拉取自己的数据时,只要根据索引读取每个磁盘文件中的部分数据即可。
39.总结spark的优化 10个以上
1:避免创建重复的RDD
2:尽可能使用同一个RDD
3:对多次使用的RDD进行持久化
4:尽量避免使用shuffle类算子
5:使用map-side 预聚合的shuffle操作
6:使用高性能的算子
7:广播大变量
8:使用Kryo优化序列化性能
9:优化数据结构
10:资源调优
11:参数调优
12:设置合理的并行度
13:spark调优数据倾斜调优
40.如何代替join
Broadcast + map + filter 代替 join
对于join,大表join小表,可以考虑把小表的数据广播到executor中,通过map + filter的操作完成join的功能
41.spark的序列化?
java序列化和kryo序列化,
kryo序列化比java序列化后的数据容量小,传输速度还快,但是java支持的类型比kryo多比较成熟。
42.spark 如何设置并行度?
1. spark.defalut.parallelism 默认是没有值的,如果设置了值比如说10,
是在shuffle的过程才会起作用(val rdd2 = rdd1.reduceByKey(_+_) //rdd2的分区数就是10,rdd1的分区数不受这个参数的影响)
conf.set(“spark.defalut.parallelism”,”500“)
2、如果读取的数据在HDFS上,增加block数,默认情况下split与block是一对一的,而split又与RDD中的partition对应,所以增加了block数,也就提高了并行度。
3、RDD.repartition,给RDD重新设置partition的数量
4、reduceByKey的算子指定partition的数量
val rdd2 = rdd1.reduceByKey(_+_,10) val rdd3 = rdd2.map.filter.reduceByKey(_+_)
5、val rdd3 = rdd1.join(rdd2) rdd3里面partiiton的数量是由父RDD中最多的partition数量来决定,因此使用join算子的时候,增加父RDD中partition的数量。
6、spark.sql.shuffle.partitions //spark sql中shuffle过程中partitions的数量
43.spark的数据倾斜? 如何解决? 总结 5条
数据倾斜的概念:一批数据中相同key的数据过多而导致其他reducetask跑完,而一个reducetask迟迟跑不完,甚至触发OOM的现象,称为数据倾斜。
1、使用Hive ETL预处理数据
2、过滤少数导致倾斜的key
3、提高shuffle操作的并行度
4、两阶段聚合(局部聚合+全局聚合)
5、将reduce join转为map join
6、采样倾斜key并分拆join操作
7、使用随机前缀和扩容RDD进行join
8、多种方案组合使用
44.spark配置优先级?
代码 脚本 配置文件 , 优先级依次降低的
1、用户代码中显式调用set()方法设置的选项 (优先级最高)
2、通过 spark-submit 传递的参数
3、写在配置文件中的值
4、系统的默认值
SPARK STREAMING
45.什么是spark streaming?
Spark Streaming用于流式数据的处理。Spark Streaming支持的数据输入源很多,
例如:Kafka、Flume、Twitter、ZeroMQ和简单的TCP套接字等等。
数据输入后可以用Spark的高度抽象原语如:map、reduce、join、window等进行运算。
而结果也能保存在很多地方,如HDFS,数据库等。
46.Spark Streaming的核心抽象? 是什么?
Spark Streaming使用离散化流(discretized stream)作为抽象表示
47.Spark Streaming 和 storm 的区别?
实时性:storm来一条处理一条 Streaming一个批次处理一次
吞吐性:sparkStreaming微批次处理比较好
事务性容错性 :storm比较好
整合性:storm单一的组件 Streaming易整合到Spark体系
48.SparkStreaming的receiver?
长期占用一个线程,用于消费数据
49.什么是Spark SQL
Spark SQL是Spark用来处理结构化数据的一个模块,它提供了2个编程抽象:DataFrame和DataSet,并且作为分布式SQL查询引擎的作用
50:Spark SQL特点:
1)易整合
2)统一的数据访问方式
3)兼容Hive
4)标准的数据连接
51.spark 和 hive 关系?
都是以sql 的形式计算。结构化数据
spark on hive:spark计算 hive作为数据源
hive on spark:hive计算 spark代替mr 作为计算引擎
52.hive的执行引擎: mr tez spark
19.Spark SQL的核心抽象?
它提供了2个编程抽象:DataFrame和DataSet
53.什么是DataFrame?
与RDD类似,DataFrame也是一个分布式数据容器。
54.什么是DataSet?
DataSet是分布式的数据集合。是Dataframe API的一个扩展,Spark最新的数据抽象。它集中了RDD的优点(强类型和可以用强大lambda函数)以及Spark SQL优化的执行引擎。DataSet可以通过JVM的对象进行构建,可以用函数式的转换(map/flatmap/filter)进行多种操作。
55.rdd DF DS 之间的区别?
1. RDD:
1)RDD一般和spark mllib同时使用
2)RDD不支持sparksql操作
2. DataFrame:
1)与RDD和Dataset不同,DataFrame每一行的类型固定为Row,每一列的值没法直接访问,只有通过解析才能获取各个字段的值
2)DataFrame与Dataset一般不与spark mlib同时使用
3)DataFrame与Dataset均支持sparksql的操作,比如select,groupby之类,还能注册临时表/视窗,进行sql语句操作
4)DataFrame与Dataset支持一些特别方便的保存方式,比如保存成csv,可以带上表头,利用这样的保存方式,可以方便的获得字段名和列的对应,而且分隔符(delimiter)可以自由指定。
3. Dataset:
1)Dataset和DataFrame拥有完全相同的成员函数,区别只是每一行的数据类型不同。
2)DataFrame也可以叫Dataset[Row],每一行的类型是Row,值没法直接访问,只有通过解析才能获取各个字段的值。而Dataset中,自定义了case class之后可以很自由的获得每一行的信息 ,当要写一些适配性很强的函数时,行的类型不确定,这时候用DataFrame即Dataset[Row]就能比较好的解决问题
56.spark sql 的执行计划?
<1:解析:对写入的sql语句进行词法和语法解析,并形成逻辑计划
<2:绑定:将SQL语句和数据库的数据字典(列,表,视图等)进行绑定
<3:优化:对逻辑计划进行优化 选择最优计划
<4:执行:生成最优的物理计划进行执行,转化为rdd
57.RDD转换为DateFrame?
rdd.toDF
58.Rdd创建DF 的方式?
SparkSQL能够自动将包含有case类的RDD转换成DataFrame,case类定义了table的结构,case类属性通过反射变成了表的列名。