1、Spark的优点和缺点是什么?
优点:
- 速度快=>内存(基于内存的分布式计算)
- 高兼容=>(多模式部署,HDFS,mysql、Hive操作)
- 多模式=>(算子,SQL,流,图,机器学习)
- 高容错=>(DAG Lineage调度快速恢复)?
- 高灵活=>持久化(内存+磁盘)
缺点
- 多线程模式,不支持细粒度划分
- 容易造成内存溢出
2、Spark 中reduceBykey和groupByKey区别与用法?哪个效果更好一些?
- reduceByKey的返回值[K,V] groupByKey的返回值[K,Iterable]
- reduceByKey包含分组和聚合,groupByKey只有分组
- 只分组不聚合用groupByKey,既分组又聚合时用reduceByKey
- 既分组又聚合时,reduceByKey在shuffle前对相同key进行预聚合,减少了落盘的数据量,效率更高效果更好
3、谈一谈你对RDD的理解?
官方文档:
- muti partition:多分区
- a function:是一个函数
- a list of dependencies:从上一级RDD推演出下一个RDD,容错,narrow和widdependencies
- opt:a Partitioner:可选分区;键值类型的RDD可以指定分区,不指定的是hashPartition
- opt:a list of preferred locatition:地址列表,指向切片的位置,移动计算,把算子传过去即可,计算数据在driver上
RDD是弹性分布式数据集
弹性:默认写在内存,内存不足自动切换到磁盘存储;数据丢失自动恢复;
分布式:只读的、分区记录的集合,并行计算
数据集:只有计算逻辑不保存数据
4、列举几个Action和Transformation算子和相应作用(每种5个)?
5、Stage如何划分?task和job的区别以及如何划分?
根据宽依赖划分:对一个job从后往前数,遇到一个shuffle则Stage数量+1,最终Stage的数量=shuffle数量+1
每个Stage代表一个TaskSet,每个TaskSet对应到具体分区就算一个Task,Task是并行的
而Job是在执行过程中,每遇到一个Action算子划分为一个Job
6、Spark Shuffle流程?
ShuffleMapTask->shuffle write ->block cache <–shuffle read <–ShuffleReduceTask
7、宽依赖和窄依赖如何划分?groupByKey、reduceByKey、map、filter、union五种哪 些会导致宽依赖,哪些会导致窄依赖?
宽依赖是一对多或多对多,窄依赖是多对一或一对一,主要根据是否有shuffle过程来划分
宽依赖:groupByKey,reduceByKey
窄依赖:map、filter、union
join:可窄可宽,分区算法和分区数一样是窄依赖,否则是宽依赖
8、cache和persist的区别是什么?
作用缓存RDD
cache是无参数的persist,默认是仅内存的缓存方式
persist除了无参之外,还有个有参数的重载,用来设置缓存级别(内存、硬盘、序列化、备份)
9、 Spark如何优化?
-
RDD重用:借助缓存的方式,cache、persist、checkpoint
-
分区设计:太少不利于并发;太多shuffle开销越大
-
优化序列化性能:Java序列化比较重,有很多内置信息。Kyro,sereralize,对于自定义的对象不支持序列化,需要注册到序列化里
-
简化结构:不要用Java的结构,因为Java里有个对象头(Mark Word 指向类的指针,数组长度(数组对象才有),记录类信息,每个对象强关联类型,因此会很重。用scala原生的结构
-
避免shuffle:尽量避免shuffle操作,使用非shuffle的算子
-
高效算子:避免不了的话,使用xxxByKey等高效算子,可以减少数据传输
-
广播大变量:其实就是mapJoin
10、容错机制
根据血缘关系,反推出父依赖的数据,如果没找到缓存,继续往上推直到找到缓存