美文网首页大数据开发
大数据开发:Spark调优原理及思路

大数据开发:Spark调优原理及思路

作者: 成都加米谷大数据 | 来源:发表于2021-06-11 18:07 被阅读0次

    在具体的大数据应用场景下,即使是高性能的框架,也会因为各种复杂的需求,及系统长期运行造成的冗余,导致效率和性能降低,这个时候就需要考虑到调优的部分。今天的大数据开发学习分享,我们就主要来讲讲Spark框架的调优原理及思路。

    Spark运行原理

    ——每一个进程包含一个executor对象,一个executor包含一个线程池,每个线程执行一个tasks。

    线程池好处:省去了进程频繁启停开销

    Task并发度概念:

    每一个节点可以启动一个或多个executor进程;

    每一个executor进程有多个core组成,每一个core一次只能执行一个task

    Executor的内存分为3块

    •第一块:执行内存,让task执行代码时,默认占executor总内存的20%,留给程序自己

    •第二块:task通过shuffle过程拉取上一个stage的task的输出后,进行聚合等操作时使用,默认也是占20%,exectution:执行内存 join、groupby这类算子涉及内存,shuffle数据都会缓存在这个内存区,如果内存满,把数据写到磁盘(spill)

    •第三块:让RDD持久化时使用,默认占executor总内存的60%,Storage:存储cache、presist、broadcast(数据量不是特别大,进行广播 -file)数据

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

    Spark资源参数调优

    •driver-memory: 设置Driver进程的内存

    – 建议:通常不用设置,一般1G就够了,若出现使用collect算子将RDD数据全部拉取到Driver上处理,就必须确保该值足够大,否则OOM内存溢出

    •executor-memory:设置每个executor进程的内存, num-executors* numexecutors代表作业申请的总内存量(尽量不要超过最大总内存的1/3~1/2)

    – 建议:设置4G~8G较合适

    •executor-cores: 每个executor进程的CPU Core数量,该参数决定每个executor进程并行执行task线程的能力, num-executors* executor-cores代表作业申请总CPU core数(不要超过总CPU Core的1/3~1/2 )

    – 建议:设置2~4个较合适

    •num-executors:该作业总共需要多少executor进程执行

    – 建议:每个作业运行一般设置50~100个左右较合适

    •spark.default.parallelism:每个stage的默认task数量

    – 建议:设置500~1000较合适,默认一个HDFS的block对应一个task, Spark默认值偏少,这样导致不能充分利用资源

    •spark.storage.memoryFraction:设置RDD持久化数据在executor内存中能占的比例,默认0.6,即默认executor 60%的内存可以保存持久化RDD数据

    – 建议:若有较多的持久化操作,可以设置高些,超出内存的会频繁gc导致运行缓慢

    •spark.shuffle.memoryFraction: 聚合操作占executor内存的比例,默认0.2

    – 建议:若持久化操作较少,但shuffle较多时,可以降低持久化内存占比,提高shuffle操作内存占比

    Spark开发调优

    原则一:避免创建重复的RDD

    – 对同一份数据,只应该创建一个RDD,不能创建多个RDD来代表同一份数据

    – 极大浪费内存

    原则二:尽可能复用同一个RDD

    – 比如:一个RDD数据格式是key-value,另一个是单独value类型,这两个RDD的value部分完全一样,这样可以复用达到减少算子执行次数

    原则三:对多次使用的RDD进行持久化处理

    – 每次对一个RDD执行一个算子操作时,都会重新从源头处理计算一遍,计算出那个RDD出来,然后进一步操作,这种方式性能很差

    – 对多次使用的RDD进行持久化,将RDD的数据保存在内存或磁盘中,避免重复劳动

    – 借助cache()和persist()方法

    原则四:避免使用shuffle类算子

    – 在spark作业运行过程中,最消耗性能的地方就是shuffle过程

    – 将分布在集群中多个节点上的同一个key,拉取到同一个节点上,进行聚合和join处理,比如groupByKey、 reduceByKey、 join等算子,都会触发shuffle

    原则五:使用map-side预聚合的shuffle操作

    – 一定要使用shuffle的,无法用map类算子替代的,那么尽量使用map-site预聚合的算子

    – 思想类似MapReduce中的Combiner

    – 可能的情况下使用reduceByKey或aggregateByKey算子替代groupByKey算子,因为reduceByKey或aggregateByKey算子会使用用户自定义的函数对每个节点本地相同的key进行预聚合,而groupByKey算子不会预聚合

    原则六:使用Kryo优化序列化性能

    – Kryo是一个序列化类库,来优化序列化和反序列化性能

    – Spark默认使用Java序列化机制(ObjectOutputStream/ ObjectInputStream API)进行序列化和反序列化

    – Spark支持使用Kryo序列化库,性能比Java序列化库高很多, 10倍左右

    关于大数据开发学习,Spark调优原理及思路,以上就为大家做了基本的讲解了。要进行调优之前,首先一定是要对框架底层的运行原理要非常清楚的,这些之前的文章也都做过相应的介绍,大家可以结合起来看。

    相关文章

      网友评论

        本文标题:大数据开发:Spark调优原理及思路

        本文链接:https://www.haomeiwen.com/subject/yeuveltx.html