长沙尚学堂|十年树人|成就高薪
致力推动IT教育,我们正在行动    全国咨询热线:0731-83072091

2018大数据之资源调优

时间:2018-01-08 09:23:31   来源:网络转载   阅读:

    在开发完Spark作业之后,就该为作业配置合适的资源了。Spark的资源参数,基本都可以在spark-submit命令中作为参数设置。2018大数据之资源调优,分享给大家。

  Spark作业基本运行原理

  1. spark-submit提交一个Spark作业之后,这个作业就会启动一个对应的Driver进程

  2. 根据你使用的部署模式(deploy-mode:client/cluster)不同,Driver进程可能在本地启动,也可能在集群中某个工作节点上启动

  3. Driver进程本身会根据我们设置的参数,占有一定数量的内存和CPU Core

  4. Driver进程要做的第一件事情,就是向集群管理器(可以是Spark Standalone集群,也可以是YARN)申请运行Spark作业需要使用的资源。资源指的就是Executor进程。在各个工作节点上,启动一定数量的Executor进程,每个Executor进程都占有一定数量的内存和CPU Core

  5. 在申请到了作业执行所需的资源之后,Driver进程就会开始调度和执行我们编写的作业代码了

  6. Driver进程会将我们编写的Spark作业代码分拆为多个Stage,每个Stage执行一部分代码片段,并为每个Stage创建一批Task,然后将这些Task分配到各个Executor进程中执行

  7. Task是最小的计算单元,负责执行一模一样的计算逻辑(也就是我们编写的某个代码片段),只是每个Task处理的数据不同而已。一个Stage的所有Task都执行完毕之后,会在各个节点本地的磁盘文件中写入计算中间结果,然后Driver就会调度运行下一个Stage。下一个Stage的Task的输入数据就是上一个Stage输出的中间结果

  8. Spark是根据Shuffle类算子来进行Stage的划分,Shuffle算子执行之前的代码会被划分为一个Stage

  Executor的内存主要分为三块

  - 第一块是让task执行我们自己编写的代码时使用,默认是占Executor总内存的20%

  - 第二块是让Task通过Shuffle过程拉取了上一个Stage的Task的输出后,进行聚合等操作时使用,默认也是占Executor总内存的20%

  - 第三块是让RDD持久化时使用,默认占Executor总内存的60%

  参考Spark内存架构

  Task的执行速度是跟每个Executor进程的CPU Core数量有直接关系的。一个CPU Core同一时间只能执行一个线程。而每个Executor进程上分配到的多个Task,都是以每个Task一条线程的方式,多线程并发运行的。如果CPU Core数量比较充足,而且分配到的Task数量比较合理,那么通常来说,可以比较快速和高效地执行完这些Task线程

  资源参数调优

  num-executors

  设置Spark作业总共要用多少个Executor进程来执行

  Driver在向YARN集群管理器申请资源时,YARN集群管理器会尽可能按照你的设置来在集群的各个工作节点上,启动相应数量的Executor进程

  每个Spark作业的运行一般设置50~100个左右(根据集群的规模)的Executor进程比较合适,设置太少或太多的Executor进程都不好。设置的太少,无法充分利用集群资源;设置的太多的话,大部分队列可能无法给予充分的资源

  executor-memory

  设置每个Executor进程的内存

  Executor内存的大小,很多时候直接决定了Spark作业的性能,而且跟常见的JVM OOM异常,也有直接的关联

  每个Executor进程的内存设置4G~8G较为合适,num-executors乘以executor-memory,是不能超过队列的最大内存量的,Spark集群可以设置每个executor最多使用的内存大小。如果你是跟团队里其他人共享这个资源队列,那么申请的内存量最好不要超过资源队列最大总内存的1/3~1/2

  executor-cores

  设置每个Executor进程的CPU core数量

  决定了每个Executor进程并行执行task线程的能力

  数量设置为2~4个较为合适,依据资源队列的最大CPU Core限制是多少,再依据设置的Executor数量,来决定每个Executor进程可以分配到几个CPU Core

  driver-memory

  设置Driver进程的内存

  Driver的内存通常来说不设置,或者设置1G左右应该就够了

  如果需要使用 collect 算子将RDD的数据全部拉取到Driver上进行处理,那么必须确保Driver的内存足够大,否则会出现OOM内存溢出的问题

  spark.default.parallelism

  设置每个stage的默认task数量

  不去设置这个参数,那么Spark根据底层HDFS的block数量来设置task的数量,默认是一个HDFS block对应一个task,通常来说,Spark默认设置的数量是偏少的

  设置该参数为num-executors * executor-cores的2~3倍较为合适

  如果task数量偏少的话,Executor进程可能根本就没有task执行,也就是白白浪费了资源

  spark.storage.memoryFraction

  设置RDD持久化数据在Executor内存中能占的比例,默认是0.6

  根据你选择的不同的持久化策略,如果内存不够时,可能数据就不会持久化,或者数据会写入磁盘

  如果Spark作业中,有较多的RDD持久化操作,该参数的值可以适当提高一些

  如果Spark作业中的Shuffle类操作比较多,而持久化操作比较少,那么这个参数的值适当降低一些比较合适

  如果发现作业由于频繁的GC导致运行缓慢(通过Spark WebUI可以观察到作业的GC耗时),意味着Task执行用户代码的内存不够用,那么同样建议调低这个参数的值

  spark.shuffle.memoryFraction

  设置Shuffle过程中一个task拉取到上个Stage的Task的输出后,进行聚合操作时能够使用的Executor内存的比例,默认是0.2

  Shuffle操作在进行聚合时,如果发现使用的内存超出了这个20%的限制,那么多余的数据就会溢写到磁盘文件中去,此时就会极大地降低性能

  如果Spark作业中的RDD持久化操作较少,Shuffle操作较多时,建议降低持久化操作的内存占比,提高Shuffle操作的内存占比比例

  如果发现作业由于频繁的GC导致运行缓慢,意味着Task执行用户代码的内存不够用,那么同样建议调低这个参数的值

  示例

  #args :

  /usr/local/spark/bin/spark-submit --class Process \

  --master yarn-cluster \

  --name Process \

  --queue fetech \

  --num-executors 20 \

  --driver-memory 5g \

  --executor-memory 4g \

  --executor-cores 2 \

  --conf spark.default.parallelism=500 \

  --conf spark.storage.memoryFraction=0.5 \

  /process.jar $1 $2 $3 $4

  2018大数据之资源调优,就跟大家讲到这里,欢迎大家点击弹窗私聊长沙尚学堂客服,免费领取大数据教学视频!
 

学大数据

  推荐阅读:

  2018长沙最好的大数据培训学校排行榜

  2018长沙哪里学大数据比较好,学费贵不贵

  大数据工程师薪资待遇怎么样,发展空间大不大 

标签:学大数据
分享:0
开班计划

试听申请表

全程面授,不高薪都难

报名成功后,尚学堂工作人员将在24小时内与您联系

热门文章
视频下载
猜你喜欢

有位老师想和您聊一聊