抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

码猿不正经

1.阐述下对Spark的并行度理解

​ Spark作业中 ,各个stage的task的数量 ,代表Spark作业在各个阶段stage的并行度。 分为资源并行度(物理并行度)数据并行度(逻辑并行度)

  • 资源并行度:由节点数(executor)和cpu数(core)决定的
  • 数据并行度:task的数量,partition大小
    • task又分为map时的task和reduce(shuffle)时的task;
    • task的数目和很多因素有关:资源的总core数,spark.default.parallelism参数spark.sql.shuffle.partitions参数,读取数据源的类型,shuffle方法的第二个参数,repartition的数目等等。

​ 如果Task的数量多,能用的资源也多,那么并行度自然就好。如果Task的数据少,资源很多有一定的浪费,但是也还好。如果Task数目很多,但是资源少,那么会执行完一批,再执行下一批。所以官方给出的建议是,这个Task数目要是core总数的2-3倍为佳。如果core有多少Task就有多少那么有些比较快的task执行完了,一些资源就会处于等待的状态。

如何设置Task数量:

​ 理想情况下将Task数量设置成与Application总CPUCore数量相同(理想情况,150个core,分配150Task),官方推荐Task数量设置成Application总CPUCore数量的2-3倍(150个cpucore,设置task数量为300-500)

​ 与理想情况不同的是:有些Task会运行快一点,比如50s就完了,有些Task可能会慢一点,要一分半才运行完,所以如果你的Task数量刚好设置的跟CPUCore数量相同,也可能会导致资源的浪费,比如150Task,10个先运行完了,剩余140个还在运行,但是这个时候就有10个core会处于等待状态。

2.设置Application的并行度

​ 参数spark.default.parallelism默认是没有值的,如果设置了值,是在shuffle的过程才会起作用

1
2
3
new SparkConf().set("spark.default.parallelism","10")
// rdd2的分区数就是10,rdd1的分区数不受这个参数的影响
val rdd2 = rdd1.reduceByKey(_+_)

如何根据数据量(task数目)配置资源

​ 当提交一个Spark Application时,设置资源信息如下,基本已经达到了集群或者yarn队列的资源上限:

task没有设置或者设置的很少,比如为100个task,平均分配一下,每个executor分配到2个task,每个executor剩下的一个CPU core就浪费掉了!

​ 虽然分配充足了,但是问题是:并行度没有与资源相匹配,导致分配下去的资源都浪费掉了。合理的并行度的设置,应该要设置的足够大,大到可以完全合理的利用你的集群资源。可以调整task数目,按照原则:Task数量,设置成Application总CPU core数量的2~3倍

​ 实际项目中,往往依据数据数量(task数目)配置资源

3.Spark有几种部署方式?请分别简要论述

  • Local:

    • 运行在一台机器上 ,通常是练手或者测试环境。
  • Standalone:

    • 构建一个基于Master+Slaves的资源调度集群 ,Spark任务提交给Master运行。是Spark自身的一个调度系统。
  • Yarn:

    • Spark客户端直接连接Yarn,不需要额外构建Spark集群。有yarn-client和yarn-cluster两种模式,主要区别 在于 Driver程序的运行节点
  • Mesos :国内大环境比较少用。

    • Mesos是一个集群管理器,可以运行多个框架和应用,包括Spark。
    • 它允许资源的精细控制和隔离,适合运行多个不同的分布式应用。

4.Spark任务使用什么进行提交,javaEE界面还是脚本

Spark任务使用shell脚本进行提交

5.Spark提交作业参数(重点)

  1. 在提交任务时的几个重要参数

    1
    2
    3
    4
    5
    executor-cores —— 每个executor使用的内核数 ,默认为1 ,官方建议2-5个 
    num-executors —— 启动executors的数量 ,默认为2
    executor-memory —— executor内存大小 ,默认1G
    driver-cores —— driver使用内核数 ,默认为1
    driver-memory —— driver内存大小 ,默认512M
  2. 例如,一个提交任务如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 如果这里通过--queue 指定了队列,那么可以免去写--master
    spark-submit \
    --master local[5] \
    --driver-cores 2 \
    --driver-memory 8g \
    --executor-cores 4 \
    --num-executors 10 \
    --executor-memory 8g \
    --class PackageName.ClassName XXXX.jar \
    --name "Spark Job Name" \
    InputPath \
    OutputPath

6.简述Spark的架构与作业提交流程(画图讲解 ,注明各个部分的作用)(重点)

image-20240713215538954

7.Spark-submit 面试题

代码分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bin/spark-submit
--class com.huawei.cluster \
--master yarn-cluster \
--driver-cores 2 \
--driver-memory 30G \
--conf spark.shuffle.service.ennabled=true \
--conf spark.memory.storageFraction=0.30 \
--conf spark.memory.fraction=0.7 \
--conf spark.default.parallelism=2800 \
--conf spark.sql.shuffle.partitions1=1400 \
--conf spark.yarn.executor.memeoryOverhead=4096 \
--executor-memory 30g \
--executor-cores 8 \
--num-executors 20 \
/export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/jars/spark-examples_2.11-2.2.0.jar \
100
  • 问题1:这个任务一共需要多少的Cores和Memory

    • 答案:162cores ,630Gmemory
  • 问题2:程序运行时每个executor上的storage内存和execution内存分别是多少

    • 答案:6.3g ,14.7g
1
2
3
--executor-memory MEM	#executor内存大小 ,默认1G 
--num-executors NUM #启动executors的数量 ,默认为2
--executor-cores NUM #每个executor使用的内核数 ,默认为1 ,官方建议2-5个

Execution内存解析

​ Spark在一个Executor中的内存分为三块,一块是execution内存,一块是storage内存,一块是other内存。 上述spark-submit提交命令是spark2.x的。

​ execution和storage是Spark Executor中内存的大户 ,other占用内存相对少很多 ,这里就不说了。

​ 在spark-1.6.0以前的版本 ,execution和storage的内存分配是固定的,(称作静态内存模型) ,使用的参数配置分别 是spark.shuffle.memoryFraction( execution内存占Executor总内存大小 ,default 0.2)和spark.storage.memoryFraction ( storage内存占Executor内存大小 ,default 0.6) ,因为是1.6.0以前这两块 内存是互相隔离的,这就导致了Executor的内存利用率不高,而且需要根据Application的具体情况,使用者自己来 调节这两个参数才能优化Spark的内存使用。

​ 在spark2.x及以后的版本 ,execution内存和storage内存可以相互借用,(称作动态内存模型) ,提高了内存的Spark中内存的使用率 ,同时也减少了OOM的情况。

​ spark.memory.storageFraction (default 0.5):这个参数设置内存表示 Executor内存中 storage/(storage+execution),虽然spark-1.6.0+的版本内存storage 和execution的内存已经是可以互相借用的了,但是借用和赎回也是需要消耗性能的,所以如果明知道程序中storage 是多是少就可以调节一下这个参数。

spark.default.parallelism=2800解析

[概念解析]

​ spark中有partition的概念(和slice是同一个概念 ,在spark1.2中官网已经做出了说明) ,一般每个partition对 应一个task。在我的测试过程中,如果没有设置spark.default.parallelism参数,spark计算出来的partition非常巨大, 与我的cores非常不搭。我在两台机器上( 8cores *2 +6g * 2)上 ,spark计算出来的partition达到2.8万个 ,也就是2.9万个tasks ,每个task完成时间都是几毫秒或者零点几毫秒 ,执行起来非常缓慢。在我尝试设置了 spark.default.parallelism 后 ,任务数减少到10 ,执行一次计算过程从minute降到20second。

参数3设置

1
2
3
4
5
6
7
spark.default.parallelism只有在处理RDD时才会起作用 ,对Spark SQL的无效。

# Default number of partitions in RDDs returned by transformations like join, reduceByKey, and parallelize when not set by user.

spark.sql.shuffle.partitions则是对sparks SQL专用的设置

# Configures the number of partitions to use when shuffling data for joins or aggregations

参数4设置

1
2
3
4
5
6
7
8
9
10
11
12
13
	spark.yarn.executor.memoryOverhead,executor执行的时候,用的内存可能会超过executor-memoy,所以 会为executor额外预留一部分内存。spark.yarn.executor.memoryOverhead代表了这部分内存。这个参数如果没有 设置 ,会有一个自动计算公式(位于ClientArguments.scala中) 
如果超过spark.yarn.executor.memoryOverhead内存 ,yarn会将应用kill掉

# https://www.jianshu.com/p/391f8776e66f 参考spark-调节executor堆外内存

# https://www.cnblogs.com/colorchild/p/12175328.html 什么时候需要调节Executor的堆外内存大小?

当出现以下异常时:
shuffle file cannot find ,executor lost、task lost ,out of memory 出现这种问题的现象大致有这么两种情况:

1.Executor挂掉了 ,对应的Executor上面的block manager也挂掉了 ,找不到对应的shuffle map output文件, Reducer端不能够拉取数据

2.Executor并没有挂掉 ,而是在拉取数据的过程出现了问题。

8. 为什么要用Yarn来部署Spark?

​ 因为 Yarn 支持动态资源配置。Standalone 模式只支持简单的固定资源分配策略,每个任务固定数量的 core,各 Job 按顺序依次分配资源,资源不够的时候就排队。这种模式比较适合单用户的情况,多用户的情境下,会有可能有些用户的任务得不到资源。

​ Yarn 作为通用的种子资源调度平台 ,除了 Spark 提供调度服务之外 ,还可以为其他系统提供调度 ,如 Hadoop MapReduce, Hive 等。

9.Spark作业提交流程是怎么样的

  1. spark-submit 提交代码,执行 new SparkContext(),在 SparkContext 里构造 DAGScheduler 和 TaskScheduler。

  2. TaskScheduler 会通过后台的一个进程 ,连接 Master ,向 Master 注册 Application。

  3. Master 接收到 Application 请求后,会使用相应的资源调度算法,在 Worker 上为这个 Application 启动 多个 Executer。

  4. Executor 启动后,会自己反向注册到 TaskScheduler 中。 所有 Executor 都注册到 Driver 上之后, SparkContext 结束初始化 ,接下来往下执行我们自己的代码。

  5. 每执行到一个 Action,就会创建一个 Job。Job 会提交给 DAGScheduler。

  6. DAGScheduler 会将 Job划分为多个 stage,然后每个 stage 创建一个 TaskSet。

  7. TaskScheduler 会把每一个 TaskSet 里的 Task,提交到 Executor 上执行。

  8. Executor 上有线程池,每接收到一个 Task,就用 Task Runner 封装,然后从线程池里取出一个线程执行这 个 task。(Task Runner 将我们编写的代码,拷贝,反序列化,执行 Task,每个 Task 执行 RDD 里的一个 partition)

10.Spark on yarn 作业执行流程 ,yarn-client 和 yarn cluster 有什么区别

Spark On Yarn 的优势:

  1. Spark 支持资源动态共享,运行于 Yarn 的框架都共享一个集中配置好的资源池
  2. 可以 很方便的利用 Yarn 的资源调度特性来做分类 、隔离以及优先级控制负载 ,拥有更灵活的调度策略
  3. Yarn 可以 自由地选择 executor 数量
  4. Yarn 支持 Spark 安全的集群管理器 ,使用 Yarn ,Spark 可以运行于 Kerberized Hadoop 之上 ,在它们进程之间进行安全认证

yarn-client yarn cluster 的异同

  1. 从广义上讲 ,yarn-cluster 适用于生产环境。而 yarn-client 适用于交互和调试 ,也就是希望快速地看到 application 的输出。

  2. 从深层次的含义讲 ,yarn-cluster 和 yarn-client 模式的区别其实就是 Application Master 进程的区别

    ​ yarn-cluster 模式下 ,driver 运行在 AM(Application Master)中 ,它负责向 YARN 申请资源,并监督作业的运行 状况。当用户提交了作业之后 ,就可以关掉 Client ,作业会继续在 YARN 上运行。然而 yarn-cluster 模式不适 合运行交互类型的作业。而 yarn-client 模式下,Application Master 仅仅向 YARN 请求 executor,Client 会和 请求的 container 通信来调度他们工作 ,也就是说 Client 不能离开。

评论