Spark 面试总结(2021-05-24更新)

2021-05-18

知识点1: Spark 作业提交流程

1、Spark 客户端执行脚本提交任务,启动 SparkSubmit 的 JVM 进程。
2、Spark 客户端向 Yarn 客户端进行通信,Yarn 客户端收到指令后:
(1)ResourceManager 会指定一个 NodeManager 开启 ApplicationMaster 进程。
(2)在 ApplicationMaster 进程里面开启 Driver 线程,执行用户的作业。
(3)ApplicationMaster 向 ResourceManager 注册,并申请资源
3、ResourceManager 会另外指定一个 NodeManager 去执行任务
(1)开启一个容器 Container
(2)开启 Executor 后台运行进程
(3)向另外一个 NodeManager 的 Driver 线程注册
(4)Driver 线程会在 Executor 后台进程所在的 NodeManager 开启 Executor 线程,此时 Spark 任务才真正开始被执行

知识点2: Spark WordCount

val conf = new SparkConf().setMaster("local[*]").setAppName("SparkWordCount")
val sc = new SparkContext(conf)

//args(0)表示输入文件的路径
sc.textFile(args(0))
  .flatMap(_.split(" "))
  .map((_, 1))
  .reduceByKey(_ + _)
  .foreach(println)

sc.stop()

2021-05-19

知识点3: Spark Shuffle

3.1 未优化的 HashShuffle

1、每个 Executor 端有多个 MapTask,每个 MapTask 会根据 下游 ReduceTask 的个数进行 hash 运算,落入到的 Reduce 文件序号为 hash 值 % ReduceTask 的个数。
2、在执行完 Spark 任务后,中间会产生一系列小文件,个数为 MapTask 的个数乘以 ReduceTask 的个数。接下来会按照相同的 hash 值聚合成下游的 Reduce 文件。

3.2 优化的 HashShuffle

大体过程和未优化的 HashShuffle 相同,区别是在产生一系列小文件之后,会按照 Executor 为单位,对具有相同 hash 值的文件进行合并,这样可以有效减少小文件的个数。

3.3 SortShuffle

对于每个 Executor,会有多个 MapTask。每个 MapTask 处理文件的大小达到一定的阈值(这个值是由 Spark 的动态内存管理机制来确定的)时,会对文件进行排序,此时还会得到一个 index(索引)文件用于记录关键字的序号。

3.4 Bypass 机制

1、触发条件
(1)不是预聚合算子
(2)MapTask 的个数小于 spark.shuffle.sort.bypassMergeThreshold(参数默认为200,在企业里设置为500)
2、基本原理
大体过程和 SortShuffle 类似,只是首先会将文件存入到缓冲区中,达到一定的阈值以后不会对文件进行排序操作。

知识点4: Spark 内存管理模型

4.1 静态内存管理模型

比例
存储60%
计算20%
其他20%

4.2 动态内存管理模型(Spark V1.6)

比例
存储30%
计算30%
其他40%
预留300M

案例1: 如果 Spark 计算内存不够,占用了存储的一部分内存,存储的内存不够用了,能否让计算部分归还内存?
不可以,因为计算操作没有执行完毕,释放资源会导致计算结果出现错误,因此需要等计算结束后,将存储部分的资源释放以后再归还内存。

4.3 堆外内存 vs 堆内内存

比例
堆外内存由操作系统进行管理,Spark 可以直接进行回收
内存的分配是由 UnsafeMemoryAllocator 完成的
堆内内存受到 JVM 的管理
内存的分配是由 HeapMemoryAllocator 完成的

知识点5: 3种join

5.0 适用条件

比例
hash join小表 join 小表
broadcast join小表 join 大表
sort merge join大表 join 大表

5.1 hash join

1、确定 Build Table 以及 Probe Table
(1)Build Table: 一般选择小表作为 Build Table,使用 join 字段构建 HashTable
(2)Probe Table: 对每一行数据使用 join字段进行匹配,匹配成功可以 join在一起
2、注意点: 一般会将数据缓存到内存中,如果内存存放不下需要存放到外存中。

5.2 broadcast join

基本原理: 将其中一张小表广播的记录结果查询出来,分发到另一张大表所在的分区节点上,分别并发地与分区记录进行 hash join。

5.3 sort merge join

1、将两张大表根据 join 字段重新进行分区。
2、对每个分区节点的两张表的数据,分别进行排序。
3、对排好序的两张分区表的数据执行 hash join 操作。

2021-05-24

知识点6: Spark 优化策略

1. 算子类map -> mapPartitionsmap 对每个元素进行操作、mapPartitions 对每个分区进行操作,分区内所有数据不全部处理完不释放内存
foreach -> foreachPartitions减少数据库连接操作
filter + coalesce
groupByKey -> reduceByKey
2. ExecutorExecutor 个数、Executor 内存、Executor 核心个数
3. shuffle避免 shuffle
增大 shuffle 端缓冲区大小默认为 32k
reduce 端: 增加拉取次数、增大拉取时间、增加重试次数
增大 bypassMergeThreshold默认为200,一般可以调整为500

知识点7: Spark 数据倾斜

判断是否出现数据倾斜countByKey、sample
1避免 shuffle
2增大 Executor 的并行度spark.sql.shuffle.partitions(默认200)
3单个 key: 在使用 map 算子处理的时候打上随机数的标签,然后在 Executor 端聚合的时候去掉标签
4多个 key: (1)对其中一个 RDD 打上 1~n 的随机标签,对另一个 RDD 的每个元素都打上 1-n 的随机标签
(2)首先使用抽样算子 sample 找到数据量过大的 key 的 RDD,将这些 RDD 分别从两个 RDD 中抽取出来
(3)然后将两个没有膨胀的 RDD 进行 join 操作
(4)将上面两步结果使用 union 算子结合。

知识点8: Spark 错误排查

1. 文件路径(1)生成的文件是否在 HDFS 上存在
(2)Spark 部署模式为 cluster,但默认只设置了 1 个副本
2. 内存(1)减少 Executor 的个数、Executor 的内存大小、Executor 的核心个数
(2)将多条 SQL 拆开 执行
3. 设置多队列在 Spark 执行任务的时候需要指定队列名称
4. 有状态算子需要设置检查点文件的路径

知识点9: Spark Streaming 参数

1. 第一次运行不丢失数据auto.offset.reset = earliest
2. 控制消费的速度spark.streaming.kafka.maxRatePerPartition
3. 开启背压机制spark.streaming.backpressure.enabled = true
4. 优雅关闭spark.streaming.stopGracefullyOnShutdown = true
5. 自动提交偏移量enable.auto.commit = false

知识点10: Spark 常见算子对比

1. reduceByKey 和 groupByKeyreduceByKey 在 shuffle 之前会按照 Executor 为单位进行预聚合
2. map 和 flatMapmap: 1 个输入 -> 1 个输出flatMap: 1 个输入 -> 多个输出
3. coalesce 和 repartitioncoalesce: 减少分区的个数,不会进行 shufflerepartition: 增加分区的个数,一定 shuffle
4. reduceByKey 和 updateStateByKeyupdateStateByKey 是有状态算子reduceByKey 是无状态算子
5. aggregateByKey 和 aggregateaggregateByKey 只有分区间能使用初值aggregate 分区内和分区间都使用初值

知识点12: Spark 其他知识点

1. Spark 缓存机制(1)RDD 只缓存到内存,而 DataFrame 会同时缓存到内存和磁盘
(2)cache 不会切断血缘关系,而 checkpoint 会切断血缘关系
2. Spark 的部署模式Local、Standalone、Yarn、Mesos
3. Spark 的 RDD、DataFrame 和 DataSet 的区别RDD 中的每个数据无法了解其数据结构
DataFrame 虽然知道有哪些字段,但不知道字段的类型
DataSet 既知道有哪些字段,还知道这些字段的类型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值