天天看点

基于CDH 6.3.0 搭建 Hive on Spark 及相关配置和调优

 hive默认使用的计算框架是mapreduce,在我们使用hive的时候通过写sql语句,hive会自动将sql语句转化成mapreduce作业去执行,但是mapreduce的执行速度远差于spark。通过搭建一个hive on spark可以修改hive底层的计算引擎,将mapreduce替换成spark,从而大幅度提升计算速度。接下来就如何搭建hive onspark

展开描述。

  注:集群使用的是cdh6.3.0,使用的spark版本是2.4.0,使用的集群配置为5个nodemanager节点,每台内存62.8g(64g),cpu 32 core。

1.  

配置spark

  给yarn分配完资源后,需要配置一些spark的参数,设置spark可使用的资源。包括executor和driver的内存,分配executor和设置并行度。

1)   配置executor内存

  在配置executor的内存大小的时候,需要考虑以下因素:

增加executor的内存可以优化map join。但是会增加gc的时间。在某些情况下,hdfs客户端没有并行处理多个写请求,在有多个请求竞争资源的时候会出现一个executor使用过多的core。尽可能的减少空闲的core的个数,cloudera推荐设置spark.executor.cores为4,5,6,这取决于给yarn分配的资源。本集群有155个core可用,将spark.executor.cores设置为5,这样155/5余数为0,设置为6的话会剩余5个空闲,设置为4的话有3个空闲。这样配置之后可以同时运行31个executor,每个executor最多可以运行5个任务(每个core一个)。

spark.executor.memory,hive中设置,代表hive 在 spark 上运行时每个 spark 执行程序的 java 堆栈内存的最大大小,本集群设为8g,该值不能太大也不能太小,都会导致任务直接失败。executor执行的时候,用的内存可能会超过该值设置的大小,所以会为executor额外预留一部分内存。spark.yarn.executor.memoryoverhead(hive中设置)代表了这部分内存,本集群设置为2g。

yarn.scheduler.maximum-allocation-mb这个参数表示每个container能够申请到的最大内存,一般是集群统一配置。spark中的executor进程是跑在container中,所以container的最大内存会直接影响到executor的最大可用内存。但是当设置一个比较大的内存时,日志中会报错,同时会打印这个参数的值。还有一点是要spark.yarn.executor.memoryoverhead和spark.executor.memory的和不能超过yarn.scheduler.maximum-allocation-mb(yarn参数)设置的值。本集群scheduler请求最大内存分配的是60g,即某些情况下允许所有可用内存都给某一个executor使用,预留2.8g给系统。

2)   配置driver内存

  sparkdriver

端的配置如下:

spark.driver.memory:当hive运行在spark上时,driver端可用的最大java堆内存。

spark.yarn.driver.memoryoverhead:每个driver可以额外从yarn请求的堆内存大小。这两个参数和就是yarn为driver端的jvm分配的总内存。

  spark在driver端的内存不会直接影响性能,但是在没有足够内存的情况下在driver端强制运行spark任务需要调整。本集群分别设置为3g和1g。

3)   动态分配executor(hive中设置)

  设置spark.executor.instances到最大值可以使得spark集群发挥最大性能。但是这样有个问题是当集群有多个用户运行hive查询时会有问题,应避免为每个用户的会话分配固定数量的executor,因为executor分配后不能回其他用户的查询使用,如果有空闲的executor,在生产环境中,计划分配好executor可以更充分的利用spark集群资源。

spark允许动态的给spark作业分配集群资源,cloudera推荐开启动态分配,本集群也开启该设置。

4)   设置并行度

为了更加充分的利用executor,必须同时允许足够多的并行任务。在大多数情况下,hive会自动决定并行度,但是有时候我们可能会手动的调整并行度。在输入端,maptask

的个数等于输入端按照一定格式切分的生成的数目,hiveon spark

的输入格式是combinehiveinputformat,可以根据需要切分底层输入格式。调整hive.exec.reducers.bytes.per.reducer控制每个reducer处理多少数据。但是实际情况下,spark相比于mapreduce,对于指定的hive.exec.reducers.bytes.per.reducer不敏感。我们需要足够的任务让可用的executor保持工作不空闲,当hive能够生成足够多的任务,尽可能的利用空闲的executor。

2.g1 gc

调优

参数配置的位置:spark-defaults.conf,在 spark 配置中查看如下:

具体属性名称为:spark.executor.extrajavaoptions,在“=“后面添加相关属性,本次调优中加入的参数如下:

spark.executor.extrajavaoptions=-xx:+useg1gc-xx:initiatingheapoccupancypercent=35 -xx:concgcthreads=20 -xx:+printflagsfinal

-xx:+printreferencegc  -verbose:gc

-xx:+printgcdetails -xx:+printgctimestamps -xx:+printadaptivesizepolicy

-xx:+unlockdiagnosticvmoptions -xx:+g1summarizeconcmark -xx:newratio=1

本次针对调优的sql为:

在executor页面查看显示gc占用运行时间超过10%至30%以上,严重影响程序运行效率,通过分析sql本身和gc信息发现,新生代对象很对,占用空间很大:

在新生代空间不足的情况下会放到老年代,容易触发full gc,因此将newratio参数调至1,有效缓解。也试过将参数调至1以下,但是会导致程序挂起长时间不执行,原因未知。另外考虑到本例中子查询数据量很大,在g1调优时适当的增加spark.executor.memory的值。

完整的g1参数和说明如下:

<col>

选项/默认值

说明

-xx:+useg1gc

使用 g1 (garbage first) 垃圾收集器

-xx:maxgcpausemillis=n

设置最大gc停顿时间(gc pause time)指标(target). 这是一个软性指标(soft goal), jvm 会尽量去达成这个目标.

-xx:initiatingheapoccupancypercent=n

启动并发gc周期时的堆内存占用百分比. g1之类的垃圾收集器用它来触发并发gc周期,基于整个堆的使用率,而不只是某一代内存的使用比. 值为 0 则表示"一直执行gc循环". 默认值为 45.

-xx:newratio=n

新生代与老生代(new/old generation)的大小比例(ratio). 默认值为 2.

-xx:survivorratio=n

eden/survivor 空间大小的比例(ratio). 默认值为 8.

-xx:maxtenuringthreshold=n

提升年老代的最大临界值(tenuring threshold). 默认值为 15.

-xx:parallelgcthreads=n

设置垃圾收集器在并行阶段使用的线程数,默认值随jvm运行的平台不同而不同.

-xx:concgcthreads=n

并发垃圾收集器使用的线程数量. 默认值随jvm运行的平台不同而不同.

-xx:g1reservepercent=n

设置堆内存保留为假天花板的总量,以降低提升失败的可能性. 默认值是 10.

-xx:g1heapregionsize=n

使用g1时java堆会被分为大小统一的的区(region)。此参数可以指定每个heap区的大小. 默认值将根据 heap size 算出最优解. 最小值为 1mb

-xx:+printflagsfinal -xx:+printreferencegc  -verbose:gc -xx:+printgcdetails -xx:+printgctimestamps -xx:+printadaptivesizepolicy

这些参数用来在stdout中打印gc相关信息,用于查看jvm中垃圾回收情况

3.

遇到的问题

q 1:

基于CDH 6.3.0 搭建 Hive on Spark 及相关配置和调优

a1:

this issue occurs when hive connection is used in threads. when onethread using hive connection is executing a query while another thread is trying

close the same hive connection

q2:

基于CDH 6.3.0 搭建 Hive on Spark 及相关配置和调优

a2:

spark.default.parallelism=1000

spark.storage.memoryfraction=0.5

spark.shuffle.memoryfraction=0.3

q3:

基于CDH 6.3.0 搭建 Hive on Spark 及相关配置和调优

a3:将该值设置大一点

基于CDH 6.3.0 搭建 Hive on Spark 及相关配置和调优

q4:yarn 初始化失败

基于CDH 6.3.0 搭建 Hive on Spark 及相关配置和调优

a4:

yarn配置中查找yarn.nodemanager.local-dirs,然后删除目录下面usercache中的所有内容,如:rm -rf /data/yarn/nm/usercache/