前言
之前在Hive on Spark跑测试时,100g的数据量要跑??个?时,?看CPU和内存的监控,发现 POWER_TEST阶段(依次执?30个查询)CPU只?了百分之??,也就是没有把整个集群的性能利?起来,导致跑得很慢。因此,如何调整参数,使整个集群发挥最?性能显得尤为重要。
Spark作业运?原理
详细原理见上图。我们使?spark-submit提交?个Spark作业之后,这个作业就会启动?个对应的Driver进程。根据你使?的部署模式(deploy-mode)不同,Driver进程可能在本地启动,也可能在集群中某个?作节点上启动。Driver进程本?会根据我们设置的参数,占有?定数量的内存和CPU core。?Driver进程要做的第?件事情,就是向集群管理器(可以是Spark Standalone集群,也可以是其他的资源管理集群,美团·?众点评使?的是YARN作为资源管理集群)申请运?Spark作业需要使?的资源,这?的资源指的就是Executor进程。YARN集群管理器会根据我们为Spark作业设置的资源参数,在各个?作节点上,启动?定数量的Executor进程,每个Executor进程都占有?定数量的内存和CPU core。
Spark是根据shuffle类算?来进?stage的划分。如果我们的代码中执?了某个shuffle类算?(?如reduceByKey、join等),那么就会在该算?处,划分出?个stage界限来。可以?致理解为,shuffle算?执?之前的代码会被划分为?个stage,shuffle算?执?以及之后的代码会被划分为下?个stage。因此?个stage刚开始执?的时候,它的每个task可能都会从上?个stage的task所在的节点,去通过?络传输拉取需要??处理的所有key,然后对拉取到的所有相同的key使?我们??编写的算?函数执?聚合操作(?如reduceByKey()算?接收的函数)。这个过程就是shuffle。
task的执?速度是跟每个Executor进程的CPU core数量有直接关系的。?个CPU core同?时间只能执??个线程。?每个Executor进程上分配到的多个task,都是以每个task?条线程的?式,多线程并发运?的。如果CPU core数量?较充?,?且分配到的task数量?较合理,那么通常来说,可以?较快速和?效地执?完这些task线程。
?参数调优
了解完了Spark作业运?的基本原理之后,对资源相关的参数就容易理解了。所谓的Spark资源参数调优,其实主要就是对Spark运?过程中各个使?资源的地?,通过调节各种参数,来优化资源使?的效率,从?提升Spark作业的执?性能。以下参数就是Spark中主要的资源 参数,每个参数都对应着作业运?原理中的某个部分。
num-executors/spark.executor.instances
参数说明:该参数?于设置Spark作业总共要?多少个Executor进程来执?。Driver在向YARN集群管理器申请资源时,YARN集群管理器会尽可能按照你的设置来在集群的各个?作节点上,启动相应数量的Executor进程。这个参数?常之重要,如果不设置的话,默 认只会给你启动少量的Executor进程,此时你的Spark作业的运?速度是?常慢的。 参数调优建议:每个Spark作业的运??般设置50~100个左右的Executor进程?较合适,设置太少或太多的Executor进程都不好。 设置的太少,?法充分利?集群资源;设置的太多的话,?部分队列可能?法给予充分的资源。
executor-memory/spark.executor.memory
参数说明:该参数?于设置每个Executor进程的内存。Executor内存的??,很多时候直接决定了Spark作业的性能,?且跟常见的JVM OOM异常,也有直接的关联。
参数调优建议:每个Executor进程的内存设置4G~8G较为合适。但是这只是?个参考值,具体的设置还是得根据不同部门的资源队列来定。可以看看??团队的资源队列的最?内存限制是多少,num-executors乘以executor-memory,是不能超过队列的最?内存量的。此外,如果你是跟团队?其他?共享这个资源队列,那么申请的内存量最好不要超过资源队列最?总内存的1/3~1/2,避免你??的Spark作业占?了队列所有的资源,导致别的同学的作业?法运?。
executor-cores/spark.executor.cores
参数说明:该参数?于设置每个Executor进程的CPU core数量。这个参数决定了每个Executor进程并?执?task线程的能?。因为每个CPU core同?时间只能执??个task线程,因此每个Executor进程的CPU core数量越多,越能够快速地执?完分配给??的所有task线程。
参数调优建议:Executor的CPU core数量设置为2~4个较为合适。同样得根据不同部门的资源来定,可以看看??的资源队列的最?CPU core限制是多少,再依据设置的Executor数量,来决定每个Executor进程可以分配到?个CPU core。同样建议,如果是跟他?共享这个队列,那么num-executors * executor-cores不要超过队列总CPU core的1/3~1/2左右?较合适,也是避免影响其他 同学的作业运?。
driver-memory
参数调优建议:Driver的内存通常来说不设置,或者设置1G左右应该就够了。唯?需要注意的?点是,如果需要使?collect算?将RDD的数据全部拉取到Driver上进?处理,那么必须确保Driver的内存?够?,否则会出现OOM内存溢出的问题。
spark.default.parallelism
参数说明:该参数?于设置每个stage的默认task数量。这个参数极为重要,如果不设置可能会直接影响你的Spark作业性能。
参数调优建议:Spark作业的默认task数量为500~1000个较为合适。很多同学常犯的?个错误就是不去设置这个参数,那么此时就会导致Spark??根据底层HDFS的block数量来设置task的数量,默认是?个HDFS block对应?个task。通常来说,Spark默认设置的数量是偏少的(?如就??个task),如果task数量偏少的话,就会导致你前?设置好的Executor的参数都前功尽弃。试想?下,?论你的Executor进程有多少个,内存和CPU有多?,但是task只有1个或者10个,那么90%的Executor进程可能根本就没有task执?,也就是??浪费了资源!因此Spark官?建议的设置原则是,设置该参数为num-executors * executor-cores的2~3倍较为合适,?如Executor的总CPU core数量为300个,那么设置1000个task是可以的,此时可以充分地利?Spark集群的资源。
spark.storage.memoryFraction
参数说明:该参数?于设置RDD持久化数据在Executor内存中能占的?例,默认是0.6。也就是说,默认Executor 60%的内存,可以?来保存持久化的RDD数据。根据你选择的不同的持久化策略,如果内存不够时,可能数据就不会持久化,或者数据会写?磁盘。参数调优建议:如果Spark作业中,有较多的RDD持久化操作,该参数的值可以适当提??些,保证持久化的数据能够容纳在内存中。避免内存不够缓存所有的数据,导致数据只能写?磁盘中,降低了性能。但是如果Spark作业中的shuffle类操作?较多,?持久化操 作?较少,那么这个参数的值适当降低?些?较合适。此外,如果发现作业由于频繁的gc导致运?缓慢(通过spark web ui可以观察到作业的gc耗时),意味着task执??户代码的内存不够?,那么同样建议调低这个参数的值。
spark.shuffle.memoryFraction
参数说明:该参数?于设置shuffle过程中?个task拉取到上个stage的task的输出后,进?聚合操作时能够使?的Executor内存的?例,默认是0.2。也就是说,Executor默认只有20%的内存?来进?该操作。shuffle操作在进?聚合时,如果发现使?的内存超出了这个20%的限制,那么多余的数据就会溢写到磁盘?件中去,此时就会极?地降低性能。
参数调优建议:如果Spark作业中的RDD持久化操作较少,shuffle操作较多时,建议降低持久化操作的内存占?,提?shuffle操作的内存占??例,避免shuffle过程中数据过多时内存不够?,必须溢写到磁盘上,降低了性能。此外,如果发现作业由于频繁的gc导致 运?缓慢,意味着task执??户代码的内存不够?,那么同样建议调低这个参数的值。
调优过程
数据量:10g
?可以看出: 随着每个executor占?的CPU core数增加,q04查询的时间显著下降,q03也下降,但幅度没那么?。本次调优只设置了spark.executor.memory和spark.executor.cores两个参数,没有涉及到spark.executor.instances参数,?默认的spark.executor.instances为2,也就是每个作业只?到2个executor,因此还没将性能发挥到最佳。接下来采?100g的数据量,并且增加spark.executor.instances参数的设置。
数据量:100g
可以看出: 调优前后查询时间有了很?的飞跃;增加spark.executor.instances设置项指定每个作业占?的executor个数后性能?有很?提升(通过监控我们发现此时CPU利?率平均有好??,甚?可以?到百分之九??);?此,我们终于将整个集群性能充分发挥出来,达到?的。可以看出性能相?我们之前??的设置还是有?定提升的,?少该博客?建议的设置是?较通?的,因此之后我们都采取最后?列的设置来跑TPCx-BB测试。最后来张?图展?调优前和调优后跑100g数据的对?:调优前后
可以看出: 绝?多数查询调优前后查询时间有了极?的飞跃; 但是像q01/q04/q14…这?个查询,可能因为查询涉及到的表?较?,调优前时间就很短,因此调优后也看不出很多差别,如果想看到?的差别,可能需要提?数据量,?如1T,3T;q10和q18调优前后时间都较长,?且调优后性能没有提升,需要再深?探索下是什么原因。
最后,?调优后的集群,分别跑10g、30g、100g的数据,结果如下:
?可以看出: 随着数据量增?,很多查询时间并没有明显增加,可能是因为集群性能太强,?且数据量还不够?,可以增?数据量继续观察对于q10、q18和q30,随着数据量增?,时间明显增?,需再深?分析
hive on spark参数配置样例
set hive.execution.engine=spark; set spark.executor.memory=4g; set spark.executor.cores=2; set spark.executor.instances=40; set spark.serializer=org.apache.spark.serializer.KryoSerializer;
?
?
|