HIve,Spark性能优化

HIve,Spark性能优化

HIve 性能优化

一:map阶段的优化:主要是控制hive任务中的map数量,确定合适的map数,以及每个map处理的合适的数据量

1.适当减少map数的情况:当任务中有许多的小文件,产生很多map,一个map任务的启动时间和初始化时间远远大于逻辑处理的事件,造成资源的浪费。

合并方法如下:

set mapred.max.split.size=100000000;//(100M)
set mapred.min.split.size.per.node=100000000;
set mapred.min.split.size.per.rack=100000000;
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;//表示执行前进行小文件合并。
//大于128:按照128M分割;100~128按照100分;小于100的进行合并。

2.适当增加map数的情况:当有一个小于128M的文件有上百万的数据,字段少而且数据单位小,处理的逻辑业务比较复杂,有一个map任务去做,耗时比较大。

set mapred.reduce.tasks=10;
create table a_1 as 
select * from a distribute by rand();
//表示通过设置Map任务数来中加Map,把a表中的数据均匀的放到a_1目录下10个文件中。

3.map端的聚合:

set  hive.map.aggr=true ;(默认为true)

二:reduce阶段的优化

1.指定reduce的数量

 set mapred.reduce.tasks=10

未指定reduce数量

param1:hive.exec.reducers.bytes.per.reducer(默认为1000^3)
param2:hive.exec.reducers.max(默认为999)
reduceNum = min(param2,总输入数据量/param1(reduceNum = InputFileSize / bytes per reducer))

因为map阶段的输出结果比输入结果减少很多,所以即使不设定reducer的个数,重设参数2还是很有必要的。可以将参数2设定为0.95*(集群中tasktracker个数)

其他详解:https://blog.csdn.net/zdy0_2004/article/details/81613230

spark 性能优化

包括运行前的资源参数设置调优,数据倾斜的解决,内存溢出,shuffle的调优,

一:参数优化部分

1.spark.driver.memory (default 1g) 增加driver的内存

SparkContext,DAGScheduler都是运行在Driver端的。对应rdd的Stage切分也是在Driver端运行,如果用户自己写的程序有过多的步骤,切分出过多的Stage,这部分信息消耗的是Driver的内存,这个时候就需要调大Driver的内存

2.spark.rdd.compress (default false) 开启rdd的压缩

这个参数在内存吃紧的时候,又需要persist数据有良好的性能,就可以设置这个参数为true,这样在使用persist(StorageLevel.MEMORY_ONLY_SER)的时候,就能够压缩内存中的rdd数据。减少内存消耗,就是在使用的时候会占用CPU的解压时间。

3.选择spark的序列化方式

建议设置为 org.apache.spark.serializer.KryoSerializer,因为KryoSerializer比JavaSerializer快,但是有可能会有些Object会序列化失败,这个时候就需要显示的对序列化失败的类进行KryoSerializer的注册,这个时候要配置spark.kryo.registrator参数或者使用参照如下代码:  valconf=newSparkConf().setMaster(…).setAppName(…)  conf.registerKryoClasses(Array(classOf[MyClass1],classOf[MyClass2]))  valsc =newSparkContext(conf)

4.spark.speculation (default false)

一个大的集群中,每个节点的性能会有差异,spark.speculation这个参数表示空闲的资源节点会不会尝试执行还在运行,并且运行时间过长的Task,避免单个节点运行速度过慢导致整个任务卡在一个节点上。这个参数最好设置为true。与之相配合可以一起设置的参数有spark.speculation.×开头的参数。参考中有文章详细说明这个参数。

二: 数据倾斜(略)

三:Spark 内存溢出:主要有map阶段中内存溢出,shuffle后内存溢出

1.map过程产生大量对象导致内存溢出

如:

rdd.map(x=>for(i <- 1 to 10000) yield i.toString)  可以调整为rdd.repartition(10000).map(x=>for(i <- 1 to 10000) yield i.toString) 

2.数据不平衡导致内存溢出

解决方案就是同上调用repartition重新分区

3.shuffle后内存溢出

解决方案 默认是HashPatitioner,默认值是父RDD中最大的分区数,这个参数通过spark.default.parallelism控制(,只对HashPatitioner有用。如果是自己实现的partitoner则需要自己在实现的代码中更改partitioner的数量。

4.共用对象能减少OOM的情况。

具体详见:https://blog.csdn.net/qq_35036995/article/details/80795078

四:shuffle调优

1.spark.shuffle.file.buffer

  • 默认值:32k
  • 参数说明:该参数用于设置shuffle write task的BufferedOutputStream的buffer缓冲大小。将数据写到磁盘文件之前,会先写入buffer缓冲中,待缓冲写满之后,才会溢写到磁盘。
  • 调优建议:如果作业可用的内存资源较为充足的话,可以适当增加这个参数的大小(比如64k),从而减少shuffle write过程中溢写磁盘文件的次数,也就可以减少磁盘IO次数,进而提升性能。在实践中发现,合理调节该参数,性能会有1%~5%的提升。

2.spark.reducer.maxSizeInFlight

  • 默认值:48m
  • 参数说明:该参数用于设置shuffle read task的buffer缓冲大小,而这个buffer缓冲决定了每次能够拉取多少数据。
  • 调优建议:如果作业可用的内存资源较为充足的话,可以适当增加这个参数的大小(比如96m),从而减少拉取数据的次数,也就可以减少网络传输的次数,进而提升性能。在实践中发现,合理调节该参数,性能会有1%~5%的提升。

3.spark.shuffle.io.maxRetries

  • 默认值:3
  • 参数说明:shuffle read task从shuffle write task所在节点拉取属于自己的数据时,如果因为网络异常导致拉取失败,是会自动进行重试的。该参数就代表了可以重试的最大次数。如果在指定次数之内拉取还是没有成功,就可能会导致作业执行失败。
  • 调优建议:对于那些包含了特别耗时的shuffle操作的作业,建议增加重试最大次数(比如60次),以避免由于JVM的full gc或者网络不稳定等因素导致的数据拉取失败。在实践中发现,对于针对超大数据量(数十亿~上百亿)的shuffle过程,调节该参数可以大幅度提升稳定性。

4.spark.shuffle.io.retryWait

  • 默认值:5s
  • 参数说明:具体解释同上,该参数代表了每次重试拉取数据的等待间隔,默认是5s。
  • 调优建议:建议加大间隔时长(比如60s),以增加shuffle操作的稳定性。

5.spark.shuffle.memoryFraction

  • 默认值:0.2
  • 参数说明:该参数代表了Executor内存中,分配给shuffle read task进行聚合操作的内存比例,默认是20%。
  • 调优建议:在资源参数调优中讲解过这个参数。如果内存充足,而且很少使用持久化操作,建议调高这个比例,给shuffle read的聚合操作更多内存,以避免由于内存不足导致聚合过程中频繁读写磁盘。在实践中发现,合理调节该参数可以将性能提升10%左右。

6.spark.shuffle.manager

  • 默认值:sort
  • 参数说明:该参数用于设置ShuffleManager的类型。Spark 1.5以后,有三个可选项:hash、sort和tungsten-sort。HashShuffleManager是Spark 1.2以前的默认选项,但是Spark 1.2以及之后的版本默认都是SortShuffleManager了。tungsten-sort与sort类似,但是使用了tungsten计划中的堆外内存管理机制,内存使用效率更高。
  • 调优建议:由于SortShuffleManager默认会对数据进行排序,因此如果你的业务逻辑中需要该排序机制的话,则使用默认的SortShuffleManager就可以;而如果你的业务逻辑不需要对数据进行排序,那么建议参考后面的几个参数调优,通过bypass机制或优化的HashShuffleManager来避免排序操作,同时提供较好的磁盘读写性能。这里要注意的是,tungsten-sort要慎用,因为之前发现了一些相应的bug。

7.spark.shuffle.sort.bypassMergeThreshold

  • 默认值:200
  • 参数说明:当ShuffleManager为SortShuffleManager时,如果shuffle read task的数量小于这个阈值(默认是200),则shuffle write过程中不会进行排序操作,而是直接按照未经优化的HashShuffleManager的方式去写数据,但是最后会将每个task产生的所有临时磁盘文件都合并成一个文件,并会创建单独的索引文件。
  • 调优建议:当你使用SortShuffleManager时,如果的确不需要排序操作,那么建议将这个参数调大一些,大于shuffle read task的数量。那么此时就会自动启用bypass机制,map-side就不会进行排序了,减少了排序的性能开销。但是这种方式下,依然会产生大量的磁盘文件,因此shuffle write性能有待提高。

8.spark.shuffle.consolidateFiles

  • 默认值:false
  • 参数说明:如果使用HashShuffleManager,该参数有效。如果设置为true,那么就会开启consolidate机制,会大幅度合并shuffle write的输出文件,对于shuffle read task数量特别多的情况下,这种方法可以极大地减少磁盘IO开销,提升性能。
  • 调优建议:如果的确不需要SortShuffleManager的排序机制,那么除了使用bypass机制,还可以尝试将spark.shffle.manager参数手动指定为hash,使用HashShuffleManager,同时开启consolidate机制。在实践中尝试过,发现其性能比开启了bypass机制的SortShuffleManager要高出10%~30%。

mapreduce 内存溢出:

reducer的默认对内存大小是200M,可以通过

conf.set(“mapreduce.admin.map.child.java.opts”, “-Xmx512m”);或者
conf.set(“mapred.map.child.java.opts”, “-Xmx512m”);设置mapper阶段的堆内存大小
conf.set(“mapreduce.admin.reduce.child.java.opts”, “-Xmx512m”)或者conf.set(“mapred.reduce.child.java.opts”, “-Xmx512m”);设置reducer阶段的堆内存大小

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页