Spark面试题(持续更新)

spark简介

Spark是一种由Scala语言开发的快速、通用、可扩展的大数据分析引擎
 Spark Core中提供了Spark最基础与最核心的功能
 Spark SQL是Spark用来操作结构化数据的组件。通过Spark SQL,用户可以使用SQL或者Apache Hive版本的SQL方言(HQL)来查询数据。
 Spark Streaming是Spark平台上针对实时数据进行流式计算的组件,提供了丰富的处理数据流的API。
 Spark主要功能主要是用于数据计算,所以其实Spark一直被认为是Hadoop MR框架的升级版

1、spark介绍

Spark是一种由Scala语言开发的快速、通用、可扩展的大数据分析引擎,Spark主要功能主要是用于数据计算,所以其实Spark一直被认为是Hadoop MR框架的升级版

2、RDD的缺点和优点

  • 自动进行内存和磁盘切换
  • 基于lineage的高效容错
  • task如果失败,会特定次数的重试
  • 数据调度弹性:DAG TASK和资源管理无关

3、Spark和Hadoop的对比

A:Spark的中间数据放到内存中,对于迭代运算效率更高。Spark更适合于迭代运算比较多的ML和DM运算。因为在Spark里面,有RDD的抽象概念。所以,Spark比Hadoop更通用

4、哪些spark算子会有shuffle?

  • 去重,distinct
  • 排序,groupByKey,reduceByKey等
  • 重分区,repartition,coalesce
  • 集合或者表操作,interection,join

5、Spark stage是如何划分的?

  • 从hdfs中读取文件后,创建 RDD 对象
  • DAGScheduler模块介入运算,计算RDD之间的依赖关系。RDD之间的依赖关系就形成了DAG
  • 每一个JOB被分为多个Stage,划分Stage的一个主要依据是当前计算因子的输入是否是确定的,如果是则将其分在同一个Stage,避免多个Stage之间的消息传递开销。
    因此spark划分stage的整体思路是:从后往前推,遇到宽依赖就断开,划分为一个stage;遇到窄依赖就将这个RDD加入该stage中。

图解:
在这里插入图片描述

6、Spark有哪些聚合类的算子,我们应该尽量避免什么类型的算子?

在我们的开发过程中,能避免则尽可能避免使用reduceByKey、join、distinct、repartition等会进行shuffle的算子,尽量使用map类的非shuffle算子。这样的话,没有shuffle操作或者仅有较少shuffle操作的Spark作业,可以大大减少性能开销。

7、你所理解的Spark的shuffle过程?

首先每一个Mapper会根据Reducer的数量创建出相应的bucket,bucket的数量是MM×RR,其中MM是Map的个数,RR是Reduce的个数。
其次Mapper产生的结果会根据设置的partition算法填充到每个bucket中去。这里的partition算法是可以自定义的,当然默认的算法是根据key哈希到不同的bucket中去。
当Reducer启动时,它会根据自己task的id和所依赖的Mapper的id从远端或是本地的block manager中取得相应的bucket作为Reducer的输入进行处理。

8、对于Spark中的数据倾斜问题,你有什么好的方案?

1、前提是定位数据倾斜,是OOM了,还是任务执行缓慢,看日志,看WebUI
2、解决方法,有多个方面

  • 避免不必要的shuffle,如使用广播小表的方式,将reduce-side-join提升为map-side-join

  • 分拆发生数据倾斜的记录,分成几个部分进行,然后合并join后的结果

  • 改变并行度,可能并行度太少了,导致个别task数据压力大

  • 两阶段聚合,先局部聚合,再全局聚合

  • 自定义paritioner,分散key的分布,使其更加均匀

9、Spark为什么要持久化,一般什么场景下要进行persist操作?

为什么要进行持久化?
spark所有复杂一点的算法都会有persist身影,spark默认数据放在内存,spark很多内容都是放在内存的,非常适合高速迭代,1000个步骤
只有第一个输入数据,中间不产生临时数据,但分布式系统风险很高,所以容易出错,就要容错,rdd出错或者分片可以根据血统算出来,如果没有对父rdd进行persist 或者cache的化,就需要重头做。
以下场景会使用persist
1)某个步骤计算非常耗时,需要进行persist持久化
2)计算链条非常长,重新恢复要算很多步骤,很好使,persist
3)checkpoint所在的rdd要持久化persist,
lazy级别,框架发现有checnkpoint,checkpoint时单独触发一个job,需要重算一遍,checkpoint前
要持久化,写个rdd.cache或者rdd.persist,将结果保存起来,再写checkpoint操作,这样执行起来会非常快,不需要重新计算rdd链条了。checkpoint之前一定会进行persist。
4)shuffle之后为什么要persist,shuffle要进性网络传输,风险很大,数据丢失重来,恢复代价很大
5)shuffle之前进行persist,框架默认将数据持久化到磁盘,这个是框架自动做的。

10、介绍一下join操作优化经验?

join其实常见的就分为两类: map-side join 和 reduce-side join。当大表和小表join时,用map-side join能显著提高效率。将多份数据进行关联是数据处理过程中非常普遍的用法,不过在分布式计算系统中,这个问题往往会变的非常麻烦,因为框架提供的 join 操作一般会将所有数据根据 key 发送到所有的 reduce 分区中去,也就是 shuffle 的过程。造成大量的网络以及磁盘IO消耗,运行效率极其低下,这个过程一般被称为 reduce-side-join。如果其中有张表较小的话,我们则可以自己实现在 map 端实现数据关联,跳过大量数据进行 shuffle 的过程,运行时间得到大量缩短,根据不同数据可能会有几倍到数十倍的性能提升。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一起学习计算机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值