Spark on yarn 内存和CPU使用解析

spark submit提交任务流程:
Spark on yarn 使用yarn-cluster提交方式,客户端只提交app request给RS,RS启动AM(相当于Driver),
AM请求RS分资源-container,container用于启动executor。Executor反向注册到AM(Driver),Driver 发送task给executor执行。
spark任务资源使用分析:
当在集群上执行客户端提交的app时,job会被切分成stages,每个stage切分成task,每个task单独调度。
可以把executor的jvm进程看做task执行池,每个executor可以并行执行多少个task由其设定的vcore数决定。
一个container对应一个JVM进程(也就是一个executor)。

container的vcore使用说明:
1、引擎为MR、TEZ时,指定vcore数也是只使用一个vcore,因为MR和TEZ是基于进程模型实现的!
2、引擎为Spark时,指定vcore数可以生效,因为Spark是基于线程模型实现的。

spark内存管理:
spark.driver.memory:默认 512M
spark.executor.memory:默认 512M
spark.yarn.am.memory:默认 512M
spark.yarn.driver.memoryOverhead:driver memory * 0.10, with minimum of 384
spark.yarn.executor.memoryOverhead:executor memory * 0.10, with minimum of 384
spark.yarn.am.memoryOverhead:am memory * 0.10, with minimum of 384
executor-cores:executor 相当于一个进程,cores 相当于该进程里的线程

yarn.app.mapreduce.am.resource.mb:am 能申请的最大内存
yarn.nodemanager.resource.memory-mb:nodemanager 能申请的最大内存
yarn.scheduler.minimum-allocation-mb:任务调度时一个 container 可申请的最小内存,默认是1024
yarn.scheduler.maximum-allocation-mb:任务调度时一个 container 可申请的最大内存,默认是8096
yarn.scheduler.minimum-allocation-vcores:最小可申请CPU数,默认是1
yarn.scheduler.maximum-allocation-vcores:最大可申请CPU数,默认是4

YARN规整化因子,不同调度器不同,具体如下:
FIFO和Capacity Scheduler,规整化因子等于最小可申请资源量(yarn.scheduler.minimum-allocation-mb),不可单独配置。
Fair Scheduler:规整化因子通过参数yarn.scheduler.increment-allocation-mb和yarn.scheduler.increment-allocation-vcores设置,默认是1024和1。
(建议因子与最小container大小匹配)

container的内存使用说明:
yarn.scheduler.minimum-allocation-mb 是Container的内存基本单位,也就是说Container的内存必须是yarn.scheduler.minimum-allocation-mb的整数倍,
比如:yarn.scheduler.minimum-allocation-mb 设置为 2G,
如果内存申请为 512M,512+384<2048M,会被分配 2G 内存,
如果内存申请为 3G,3072+384=3456M<4096M,会被分配 4G 内存,
如果申请内存为 6G,6144+614=6758<8192M,会被分配 8G 内存, 【max(6144*0.1, 384)=614】
所以当设定–executor-memory 为3G时,Container实际内存并非3G
// Executor memory in MB.
protected val executorMemory = args.executorMemory
// Additional memory overhead.
protected val memoryOverhead: Int = sparkConf.getInt(“spark.yarn.executor.memoryOverhead”,
math.max((MEMORY_OVERHEAD_FACTOR * executorMemory).toInt, MEMORY_OVERHEAD_MIN))
一个executor实际要使用的内存大小为:totalMemory = spark.executor.memory + memoryOverhead(max(executor memory * 0.10, with minimum of 384))
参数MEMORY_OVERHEAD_FACTOR和MEMORY_OVERHEAD_MIN一般不能直接修改,是Spark代码中直接写死的!!!
通过手动设置memoryOverhead,防止内存溢出。
spark.yarn.executor.memoryOverhead
spark.yarn.driver.memoryOverhead

参数设置注意事项
executor-memory

  1. 设置过大,会导致GC过程很长,64G是推荐的内存上限
  2. 设置过小,会导致GC频繁,影响效率

executor-cores

  1. 设置过大,并行度会很高,容易导致网络带宽占满,特别是从HDFS读取数据,或者是collect数据回传Driver
  2. 设置过大,使得多个core之间争夺GC时间以及资源,导致大部分时间花在GC上
  3. HDFS Client有多个并发线程写的问题,HDFS每个Executor的使用5个任务就可获取完全并发写。因此最好每个Executor的cores不高于5.

常见问题
常见的问题无非就是 内存不足 或者 container 被杀死
Removing executor 5 with no recent heartbeats: 120504 ms exceeds timeout 120000 ms
Container killed by YARN for exceeding memory limits
Consider boosting spark.yarn.executor.memoryOverhead
spark-OutOfMemory:GC overhead limit exceeded

常规思路

  1. 第一解决办法就是增加总内存 【此法不能解决所有问题】
  2. 其次考虑数据倾斜问题,因为数据倾斜导致某个 task 内存不足,其它 task 内存足够
    // 最简单的方法是 repartition 【此法不能解决所有问题】
  3. 考虑增加每个 task 的可用内存
    // 减少 Executor 数
    // 减少 executor-cores 数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值