关于影响SparkSQL工作效率的三个方面【面试解答】

一、内存分配

众所周知,SparkSQL操作最终是要被转换为spark操作的,而Spark是基于内存运算的,不管是运算还是shuffle操作亦或是persist/cache操作,都需要内存资源,这些操作的内存资源的在一个执行者进程所拥有的内存占比可以通过参数指定。
举个例子来说,当shuffle和cache的内存占比比较低,那么用于计算的内存就越高,但这又会使得用于cache受限,而cache操作本身也是为了提高运算效率,分配的过多或者过少都会影响效率,不是很好衡量,调试这cache和shuffle这两个参数需要很丰富的经验。

二、任务调度

Spark的任务就处理海量大数据集,这些大数据集在表面看来是一个整体,但是在内部是分区的,这些分区的数据散布在spark集群的各台机器上被并行处理,执行的效率在于并行度,即每个task的线程数。
拿集群中的机器来说,比如有10台机器,每台机器有12G内存,都是4核,那这个集群的运算资源就是有120G内存资源,共有40个cpu内核,现在有个任务,设立并发度为30,那每个执行者进程分到3个task任务,但是每个执行者线程有4个内核,多出来一个没有派上用场,这时候其实设立并发度大于等于40比较合适,让并发度尽量跟资源吻合,也可以让每个task分得的数据变小,缩短执行时间,这其中的衡量一样也需要丰富的经验。
另一方而言,并行度的设计也要根据任务数据量大小来计算,因为同一个stage的task运行速度不同,并行度往往是要大于内核总限制的,这个并发度的数量要参考每个执行者进程分得的task数目乘以每个task需要的运行内存不得大于执行者线程所拥有的内存资源,否则也会影响性能,甚至报错。

三、磁盘IO

一个集群效率的上限制往往是磁盘IO,也就是因为磁盘读写太慢,spark才会被设计成基于内存运算,然而,虽然spark号称基于内存运算,但并不意味着它能够就此完全摆脱与磁盘打交道的关系。
我们都知道,spark运算的数据源往往是要依赖于hive,但是hive本身不存储数据,它的数据是存储在hdfs上的,磁盘读取的限制势必会影响到hdfs的读取与结果存放的性能,而作为组成这个庞大的分布式文件系统的各个节点,性能上良莠不齐。
就hive执行引擎这个参数的设定不同,使得hive在执行上的性能也有不同的表现,首先就是MR,即以MapReduce的方式执行数据查询(在磁盘上)任务,同理,spark就是在内存中,tez就是将mapreducer中的map task和reduce task进一步细分,在它们内部又进行加工融合,从而使得多个map reduce之前的依赖关系被去处,转换成一个作业任务,这个过程是在内存中完成的,只会在最终与hdfs进行交互,mr2使得集群的资源更有效的利用,但总的来说,因为要避免网络IO,那么spark和hdfs最好在一个集群的相同机器上,任何一方占用的资源多或者说是执行时间长,都会使得最终任务得以完成的效率受到影响,这个调度的过程需要不断地去积累和学习。

场景:

20TB数据,用20台物理机,每台物理机16个CPU核,256G内存,总共应该设立多少个并发任务?

解析:

该场景应该从CPU核数、机器的内存峰值、每个task任务所分得的数据大小以及每个执行者进程的内存三个方面考虑,现设立并发度为x,列出以下条件:
1	x>=320
2	20000/x*16<256*40%(给物理机的百分之四十的内存用于executor执行者进程进行运算)
3	x%20==0
整理得出:3125<x且x%20==0
所以并发度设在3140比较合适
发布了31 篇原创文章 · 获赞 21 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Jack_Roy/article/details/86526629