spark性能优化
spark运行原理:
spark作业提交后,会根据我们设置的参数启动一个占有一定内存和CPU core数的Driver。Driver进程启动后会现象其群管理器申请spark作业运行所需要的资源(Executor进程)。yarn集群管理器会根据设置的资源参数在每个节点上启动一定数量的Executor进程,每个Executor进程都占有一定的内存和CPU core数。所需资源准备完成后Driver开始执行 spark作业。Driver进程将作业拆分,由多个stage分别执行,stage以shuffle操作为界,由shuffle类算子划分,每个stage中包含task,将task分配到各个executor进程中执行(task为最小的计算单元),若干个task以一条线的方式,多线程并发运行,而CPU中的每个核智一次只执行一个线程,因此task运行速度与executor的CPU核数直接相关,stage中的task全部执行完毕后将中间结果写入本地磁盘,且结果作为之后Driver进程开始运行的下一个stage的输入数据,此过程循环至所有代码执行完毕。
了解spark运行原理后可以得知,spark性能优化可由多个方面入手
spark性能优化:
提高并行度:
并行度与task数量有关,task数量越大,并行度越高,提高并行度,可以使资源得到更加充分的利用,减少单个task的数据处理量,进而增加运行速度。
提高并行度的方法:
设置task的数量。至少与CPU核数相同,理想情况下task数量应为CPU核数的2至3倍,这样有利于执行时能够随时补漏,提升速度;
设置RDD的partition数量。每个分区对应一个task,RDD分区越多,task数量越多,并行度越高。
RDD持久化:
每次对一个新的RDD进行计算都会从之前的父RDD重新开始计算,为避免一个RDD被重复计算多次而对RDD进行持久化,提升效率。
persist方法中包含较多个缓存级别,可根据不同场景设置级别;cache方法默认将数据缓存到内存中(本质上仍然调用persist方法)。
序列化:
数据缓存在内存中可能导致内存占用过大而OOM内存溢出,因此优先考虑用序列化的方式存储,将RDD每个分区的数据序列化成一个字节数组,减少内存占用。但序列化在获取数据时需要反序列化。若还是导致OOM内存溢出,则应将数据缓存至磁盘上,数据在磁盘中不需序列化。
使用fastutil优化数据格式:
fastutil集合类能够提供更小的内存占用,且有更快的存取速度,可以使用fastutil中的集合类代替JDK原生集合
分配资源:
为进程分配更多的资源是性能调优最直接也是最优先的方法,当资源不足时才考虑其他方法。可分配的资源有:executor数量,每个executor需要的核数,每个executor需要的内存大小等。
浙公网安备 33010602011771号