Hive调优技巧汇总

导读:本篇文章讲解 Hive调优技巧汇总,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

参考:http://blog.csdn.net/beckham008/article/details/23741151?utm_source=tuicool&utm_medium=referral

1.设置合理solt数


mapred.tasktracker.map.tasks.maximum 
每个tasktracker可同时运行的最大map task数,默认值2。

mapred.tasktracker.reduce.tasks.maximum
每个tasktracker可同时运行的最大reduce task数,默认值1。

2.配置磁盘块
mapred.local.dir
map task中间结果写本地磁盘路径,默认值${hadoop.tmp.dir}/mapred/local。
可配置多块磁盘缓解写压力。当存在多个可以磁盘时,Hadoop将采用轮询方式将不同的map task中间结果写到磁盘上。

3.配置RPC Handler数
mapred.job.tracker.handler.count
jobtracker可并发处理来自tasktracker的RPC请求数,默认值10。

4.配置HTTP线程数
tasktracker.http.threads
HTTP服务器的工作线程数,用于获取map task的输出结果,默认值40。

5.启用批调度

6.选择合适的压缩算法
Job输出结果是否压缩
mapred.output.compress 
是否压缩,默认值false。
mapred.output.compression.type
压缩类型,有NONE, RECORD和BLOCK,默认值RECORD。
mapred.output.compression.codec
压缩算法,默认值org.apache.hadoop.io.compress.DefaultCodec。

map task输出是否压缩
mapred.compress.map.output
是否压缩,默认值false
mapred.map.output.compression.codec
压缩算法,默认值org.apache.hadoop.io.compress.DefaultCodec。

7.设置失败容忍度
mapred.max.map.failures.percent
例如:set mapred.max.map.failures.percent=30; 
作业最多允许失败的map task比例,默认值0。
mapred.max.reduce.failures.percent
作业最多允许失败的reduce task比例,默认值0。
mapred.map.max.attempts
一个map task的最多重试次数,默认值4。
mapred.reduce.max.attempts
一个reduce task的最多重试次数,默认值4。

8.设置跳过坏记录
mapred.skip.attempts.to.start.skipping
当任务失败次数达到该值时,启用跳过坏记录功能,默认值2。
mapred.skip.out.dir
检测出的坏记录存放目录,默认值为输出目录的_logs/skip,设置为none表示不输出。
mapred.skip.map.max.skip.records
map task最多允许的跳过记录数,默认值0。
mapred.skip.reduce.max.skip.groups
reduce task最多允许的跳过记录数,默认值0。

9.配置jvm重用
mapred.job.reuse.jvm.num.tasks 
一个jvm可连续启动多个同类型任务,默认值1,若为-1表示不受限制。

10.配置jvm参数
mapred.child.java.opts
任务启动的jvm参数,默认值-Xmx200m,建议值-XX:-UseGCOverheadLimit -Xms512m -Xmx2048m -verbose:gc -Xloggc:/tmp/@taskid@.gc

11. map task调优
io.sort.mb
默认值100M
io.sort.record.percent
默认值0.05
io.sort.spill.percent
默认值0.80

12.reduce task调优
io.sort.factor
默认值10
mapred.reduce.parallel.copies
默认值5



=================================================================================
  1
.设置任务名称,方便查找监控 
  SET mapred.job.name=P_DWA_D_IA_S_USER_PROD; 
  
 
  2
.决定是否可以在 Map 端进行聚合操作 
  set hive.map.aggr=true; 
  
 
  3
.有数据倾斜的时候进行负载均衡 
  set hive.groupby.skewindata=true; 
  
 
  H
iveQL 去重操作 
  和
SQL一样,HiveQL中同样支持DISTINCT操作,如下示例: 
  (
1) SELECT count(DISTINCT uid) FROM log 
  (
2) SELECT ip, count(DISTINCT uid) FROM log GROUP BY ip 
  (
3) SELECT ip, count(DISTINCT uid, uname) FROMlog GROUP BY ip 
  (
4) SELECT ip, count(DISTINCTuid), count(DISTINCT uname) FROMlog GROUP BY ip 
  
 
  当
我们使用Hive QL中的去重关键字DISTINCT时,需要注意的一点是: 
  在
多个列上进行的去重操作与hive环境变量hive.groupby.skewindata存在关系。 
  当
hive.groupby.skewindata=true时,hive不支持多列上的去重操作,并报错: 
  E
rror in semantic analysis: DISTINCT on different columns notsupported with skew in data.  
  注
意:上面示例中的(3)不属于多列上的DISTINCT操作。 
  
 
  G
roup By 语句 
  • Map 端部分聚合:
  • 并不是所有的聚合操作都需要在 Reduce 端完成,很多聚合操作都可以先在 Map 端进行部分聚合,最后在 Reduce端得出最终结果。
  • 基于 Hash
  • 参数包括:
  • hive.map.aggr = true 是否在 Map 端进行聚合,默认为True
  • hive.groupby.mapaggr.checkinterval =100000 在 Map 端进行聚合操作的条目数目
  • 有数据倾斜的时候进行负载均衡
  • hive.groupby.skewindata = false
  • 当选项设定为 true,生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group ByKey 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce中),最后完成最终的聚合操作。
  4
.每个MapReduce作业的任务可以申请的内存资源数量 
  SET mapreduce.map.memory.mb=2048; 
  每
个MapReduce作业的map任务可以申请的内存资源数量 
  SET mapreduce.reduce.memory.mb=8192; 
  每
个MapReduce作业的reduce任务可以申请的内存资源数量 
  
 
5.对于简单的不需要聚合的类似SELECT <col> from <table> LIMIT n语句,不需要起MapReduce job,直接通过Fetch task获取数据
set hive.fetch.task.conversion=more;
  
合并小文件
6. hive.merge.mapredfiles(默认为false)
正常的map-reduce job后,是否启动merge job来合并reduce端输出的结果,建议开启

set mapred.max.split.size=524288000;
set mapred.min.split.size.per.node=471859200;
set mapred.min.split.size.per.rack=471859200;
set hive.hadoop.supports.splittable.combineinputformat=true;     
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; 

注:第四个参数存在其他参数才能生效
  

7.设置参数不走map-reduce
set hive.fetch.task.conversion=more;
 
8.hive动态分区参数设置
ive.exec.dynamic.partition=true
默认值:false
描述:是否允许动态分区
hive.exec.dynamic.partition.mode=nonstrict
默认值:strict
描述:strict是避免全分区字段是动态的,必须有至少一个分区字段是指定有值的
设置如下参数配置动态分区的使用环境:
hive.exec.max.dynamic.partitions.pernode=100
默认值:100
描述:each mapper or reducer可以创建的最大动态分区数
hive.exec.max.dynamic.partitions=1000
默认值:1000
描述:一个DML操作可以创建的最大动态分区数
hive.exec.max.created.files=100000
默认值:100000
描述:一个DML操作可以创建的文件数

  =============================================================================================================

hive.exec.reducers.bytes.per.reducer
•默认值: 1000000000 (1G)
•说明:每个reduce的接受的数据量
    如果送到reduce的数据为10G,那么将生成10个reduce任务
hive.exec.reducers.max
•默认值:999
•说明: reduce的最大个数 
hive.cli.print.header
•目前值:fasle
•说明:可以控制在处理中是否显示表列名(就是查询结果)
mapred.reduce.tasks
•默认值:-1
•说明:每个任务reduce的默认值
 -1 代表自动根据作业的情况来设置reduce的值 
hive.cli.print.current.db
•默认值:false
•说明:开启这个属性可以再CLI提示符前打印出当前所在的数据库名
hive.cli.prompt
•默认值:hive
•说明:应该就是设置“hive”为启动cli 的命令
hive.cli.pretty.output.num.cols
•默认值:-1
•说明:根据百度翻译,意思应该是根据表的列数,和你终端的宽度,自动设置你数据展现的格式。
hive.exec.scratchdir
•集群值:/tmp/hive-${user.name}
•说明:HDFS路径,用于存储不同 map/reduce 阶段的执行计划和这些阶段的中间输出结果。
hive.exec.local.scratchdir
•集群值:/tmp/${user.name}
•说明:Hive 默认的数据文件存储路径,通常为 HDFS 可写的路径。
hive.test.mode
•默认值:false
•说明:是否以测试模式运行 Hive
hive.test.mode.prefix
•默认值:test_
•说明: Hive 测试模式的前缀。
hive.test.mode.samplefreq
•默认值:32
•说明:Hive 测试模式取样的频率,即每秒钟取样的次数。
hive.test.mode.nosamplelist
•说明:Hive 测试模式取样的排除列表,以逗号分隔。
hive.metastore.uris
•说明:Hive 元数据的 URI,多个 thrift://地址,以英文逗号分隔。 
javax.jdo.option.ConnectionURL
•集群值:jdbc:derby:;databaseName=metastore_db;create=true
•说明: 元数据库的连接 URL。 
javax.jdo.option.DetachAllOnCommit
•说明:事务提交后detach所有提交的对象,默认是true;
javax.jdo.option.NonTransactionalRead
•说明:是否允许非事务的读,默认是true;

javax.jdo.option.ConnectionUserName:
username,默认APP;
javax.jdo.option.ConnectionPassword:
password,默认mine;
javax.jdo.option.Multithreaded:
是否支持并发访问metastore,默认是true;
datanucleus.connectionPoolingType:
使用连接池来访问JDBC metastore,默认是DBCP;
datanucleus.validateTables:
检查是否存在表的schema,默认是false;
datanucleus.validateColumns:
检查是否存在列的schema,默认false;
datanucleus.validateConstraints:
检查是否存在constraint的schema,默认false;
datanucleus.stroeManagerType:
元数据存储类型,默认rdbms;
datanucleus.autoCreateSchema:
在不存在时是否自动创建必要的schema,默认是true;
datanucleus.aotuStartMechanismMode:
如果元数据表不正确,抛出异常,默认是checked;
datanucleus.transactionIsolation:
默认的事务隔离级别,默认是read-committed;
datanucleus.cache.level2:
使用二级缓存,默认是false;
datanucleus.cache.level2.type:
二级缓存的类型,有两种,SOFT:软引用,WEAK:弱引用,默认是SOFT;
datanucleus.identifierFactory:
id工厂生产表和列名的名字,默认是datanucleus;
datanucleus.plugin.pluginRegistryBundleCheck:
当plugin被发现并且重复时的行为,默认是LOG;
hive.metastroe.warehouse.dir
•说明:数据仓库的位置,默认是/user/hive/warehouse;
hive.metastore.execute.setugi:
非安全模式,设置为true会令metastore以客户端的用户和组权限执行DFS操作,默认是false,这个属性需要服务端和客户端同时设置;
hive.metastore.event.listeners:
metastore的事件监听器列表,逗号隔开,默认是空;
hive.metastore.partition.inherit.table.properties
:当新建分区时自动继承的key列表,默认是空;
hive.metastore.end.function.listeners:
metastore函数执行结束时的监听器列表,默认是空;
hive.metadata.move.exported.metadata.to.trash
说明:猜测,默认值是空。应该是垃圾站,如果垃圾站被清,元数据都会被清掉。
hive.metastore.partition.name.whitelist.pattern
说明:猜测,默认值是空。应该是如果设置了规则,分区名称将会按照你的正则规则去匹配。不匹配会被拒绝创建。
hive.metastore.disallow.incompatible.col.type.change
说明: 额,集群值是空。描述中大概意思是,如果开启(默认false)则更改表字段的类型到一个不兼容的新类型是不允许的。RCFile默认SerDe(columnarserde)序列化的值在这样一种方式下数据类型可以转换成字符串的任何类型。地图也是序列化为一个字符串,它可以作为一个字符串读取。然而,任何二进制序列化,都是不行的。当ALTER TABLE尝试访问旧分区是会被阻止的。更多细节见hive-4409。
原始的类型,如int,string,bigint,等相互兼容,不阻止。
好吧。。。只能翻译成这样了。。。
hive.metastore.end.function.listeners:
metastore函数执行结束时的监听器列表,默认是空;
hive.metastore.event.expiry.duration:
事件表中事件的过期时间,默认是0;
hive.metastore.event.clean.freq:
metastore中清理过期事件的定时器的运行周期,默认是0;
hive.metastore.connect.retries:
创建metastore连接时的重试次数,默认是5;
hive.metastore.failure.retries:
创建metastore连接时的失败重试次数,默认是3;
hive.metastore.client.connect.retry.delay:
客户端在连续的重试连接等待的时间,默认1;
hive.metastore.client.socket.timeout:
客户端socket超时时间,默认20秒;
hive.metastore.rawstore.impl:
原始metastore的存储实现类,默认是org.apache.hadoop.hive.metastore.ObjectStore;
hive.metastore.batch.retrieve.max:
在一个batch获取中,能从metastore里取出的最大记录数,默认是300,集群设置值是1000;
hive.default.fileformat
•说明:Hive 默认的输出文件格式,与创建表时所指定的相同,可选项为 ‘TextFile’ (默认)、 ‘SequenceFile’ 或者 ‘RCFile’。 
hive.default.rcfile.serde:hive默认的RCFILE SerDe格式  默认:org.apache.hadoop.hive.serde2.columnar.ColumnarSerDe;
hive.fileformat.check :
Hive 是否检查输出的文件格式。默认true;
hive.map.aggr 
 •
说明: 
决定是否可以在 Map 端进行聚合操作,默认true;
hive.groupby.skewindata 
 •
说明: 
 决定 group by 操作是否支持倾斜的数据。默认是false;
hive.optimize.multigroupby.common.distincts
 
•说明:这个应该是如果一张表的查询用到相同的distinct字段,可以写成如下格式:
      from src
        insert overwrite table dest1 select col1, count(distinct colx) group by col1
        insert overwrite table dest2 select col2, count(distinct colx) group by col2;
也就是相当于一表查询,多表插入那种吧。默认是true
 hive.groupby.mapaggr.checkinterval 
  •
说明:对
于 Group By 操作的 Map 聚合的检测时间,以毫秒为单位。默认100000
hive.mapred.local.mem 
  •
说明: 
Mapper/Reducer 在本地模式的最大内存量,以字节为单位,0为不限制。 默认0。
hive.mapjoin.followby.map.aggr.hash.percentmemory:
map端聚合时hash表的内存占比,该设置约束group by在map join后进行,否则使用hive.map.aggr.hash.percentmemory来确认内存占比,默认值0.3;
hive.map.aggr.hash.force.flush.memeory.threshold:
map端聚合时hash表的最大可用内存,如果超过该值则进行flush数据,默认是0.9;
hive.map.aggr.hash.percentmemory:
map端聚合时hash表所占用的内存比例,默认0.5,这个在map端聚合开启后使用。
hive.session.history.enabled 设置为true,则会初始化日志文件,默认为false;
hive.map.aggr.hash.min.reduction 
 Hive Map 端聚合的哈稀存储的最小 reduce 比例。默认0.5;
hive.optimize.index.filter
:自动使用索引,默认不开启false;
hive.optimize.index.groupby
:是否使用聚集索引优化group-by查询,默认关闭false;
hive.optimize.ppd
:是否支持谓词下推,默认开启;所谓谓词下推,将外层查询块的 WHERE 子句中的谓词移入所包含的较低层查询块(例如视图),从而能够提早进行数据过滤以及有可能更好地利用索引。
hive.optimize.ppd.storage
:谓词下推开启时,谓词是否下推到存储handler,默认开启,在谓词下推关闭时不起作用;
hive.ppd.recognizetransivity
:在等值join条件下是否产地重复的谓词过滤器,默认开启;
hive.optimize.groupby
:在做分区和表查询时是否做分桶group by,默认开启true;
hive.optimize.skewjoin.compiletime:默认false ,这个,真没看懂百度翻译。。。。
hive.optimize.union.remove:默认false ,这个,没看懂百度翻译。。。。
hive.mapred.supports.subdirectories:默认false ,哎。。同上
hive.multigroupby.singlemr:
将多个group by产出为一个单一map/reduce任务计划,当然约束前提是group by有相同的key,默认是false;
hive.map.groupby.sorted:默认false ,看不懂。。
hive.map.groupby.sorted.testmode:默认false ,看不懂。。
hive.new.job.grouping.set.cardinality:默认30,看不懂。。
hive.join.emit.interval:
在发出join结果之前对join最右操作缓存多少行的设定,默认1000;hive jira里有个对该值设置太小的bugfix;
hive.join.cache.size:
在做表join时缓存在内存中的行数,默认25000;
hive.smbjoin.cache.rows:
在做表smb (smb不知道是啥,Sort-Merge-Bucket
) join时缓存在内存中的行数,默认10000
hive.optimize.skewjoin:
 
•说明:
是否开启数据倾斜的join优化,默认不开启false;
hive.skewjoin.key:
 
•说明:
判断数据倾斜的阈值,如果在join中发现同样的key超过该值则认为是该key是倾斜的join key,默认是100000;
hive.skewjoin.mapjoin.map.tasks:
•说明:
在数据倾斜join时map join的map数控制,默认是10000;
hive.skewjoin.mapjoin.min.split:
•说明:
数据倾斜join时map join的map任务的最小split大小,默认是33554432,该参数要结合上面的参数共同使用来进行细粒度的控制;
hive.mapred.mode:
•说明:
hive操作执行时的模式,默认是nonstrict非严格模式,如果是strict模式,很多有风险的查询会被禁止运行,比如笛卡尔积的join和动态分区;
hive.enforce.bucketmapjoin:默认false,应该是跟桶有关的join设置;
hive.exec.script.maxerrsize:
当用户调用transform或者map或者reduce执行脚本时,最大的序列化错误数,默认100000,一般也不用修改;
hive.exec.script.allow.partial.consumption:
hive是否允许脚本不从标准输入中读取任何内容就成功退出,默认关闭false;
hive.script.operator.id.env.var:
在用户使用transform函数做自定义map/reduce时,存储唯一的脚本标识的环境变量的名字,默认HIVE_SCRIPT_OPERATOR_ID;
hive.script.operator.truncate.env:默认false,知道干啥的。
hive.exec.compress.output:
•说明:
一个查询的最后一个map/reduce任务输出是否被压缩的标志,默认为false,但是一般会开启为true,好处的话,节省空间不说,在不考虑cpu压力的时候会提高io;
hive.exec.compress.intermediate:
•说明:
类似上个,在一个查询的中间的map/reduce任务输出是否要被压缩,默认false;
hive.exec.parallel:
•说明:
hive的执行job是否并行执行,默认不开启false,在很多操作如join时,子查询之间并无关联可独立运行,这种情况下开启并行运算可以大大加速;
hive.exec.parallel.thread.number:
•说明:在并行执行时的最大job数,默认是 8;
hive.exec.rowoffset:
是否提供行偏移量的虚拟列,默认是false不提供,Hive有两个虚拟列:一个是INPUT__FILE__NAME,表示输入文件的路径,另外一个是BLOCK__OFFSET__INSIDE__FILE,表示记录在文件中的块偏移量,这对排查出现不符合预期或者null结果的查询是很有帮助的;
hive.task.progress:
控制hive是否在执行过程中周期性的更新任务进度计数器,开启这个配置可以帮助job tracker更好的监控任务的执行情况,但是会带来一定的性能损耗,当动态分区标志hive.exec.dynamic.partition开启时,本配置自动开启;
hive.hwi.war.file:
hive在web接口是的war文件的路径,默认是lib/hive-hwi-xxxx(version).war;
hive.hwi.listen.host:
hwi监听的host地址,默认是0.0.0.0;
hive.hwi.listen.port:
hwi监听的端口,默认是9999;
hive.exec.pre.hooks:
执行前置条件,一个用逗号分隔开的实现了org.apache.hadoop.hive.ql.hooks.ExecuteWithHookContext接口的java class列表,配置了该配置后,每个hive任务执行前都要执行这个执行前钩子,默认是空;
hive.metastore.init.hooks:一个逗号分隔的列表钩子被调用,在hmshandler初始化开始。aninit钩指定名称为java类来扩展org.apache.hadoop.hive.metastore.metastoreinitlistener。
hive.client.stats.publishers:
做count的job的统计发布类列表,由逗号隔开,默认是空;必须实现org.apache.hadoop.hive.ql.stats.ClientStatsPublisher接口;
hive.merge.mapfiles:
•说明:
在只有map的作业结束时合并小文件,默认开启true;
hive.merge.mapredfiles:
•说明:
在一个map/reduce作业结束后合并小文件,默认不开启false;
hive.heartbeat.interval:发送心跳的时间间隔,在mapjoin和filter操作中使用,默认1000;
hive.merge.size.per.task:   疑问一体化集群没有生效。
•说明:
作业结束时合并文件的大小,默认256MB;
hive.merge.smallfiles.avgsize:
•说明:
在作业输出文件小于该值时,起一个额外的map/reduce作业将小文件合并为大文件,小文件的基本阈值,设置大点可以减少小文件个数,需要mapfiles和mapredfiles为true,默认值是16MB;

****************************************mapjoin 的参数**********************************************************


hive.mapjoin.smalltable.filesize:
输入表文件的mapjoin阈值,如果输入文件的大小小于该值,则试图将普通join转化为mapjoin,默认25MB;
hive.ignore.mapjoin.hint:  忽略mapjoin暗示 
hive.mapjoin.localtask.max.memory.usage:
mapjoin本地任务执行时hash表容纳key/value的最大量,超过这个值的话本地任务会自动退出,默认是0.9;
hive.mapjoin.followby.gby.localtask.max.memory.usage:
类似上面,只不过是如果mapjoin后有一个group by的话,该配置控制类似这样的query的本地内存容量上限,默认是0.55;
hive.mapjoin.check.memory.rows:
在运算了多少行后执行内存使用量检查,默认100000;
hive.auto.convert.join:
根据输入文件的大小决定是否将普通join转换为mapjoin的一种优化,默认不开启false;
hive.auto.convert.join.noconditionaltask:
9. 0.11中新增了一个优化参数“hive.auto.convert.join.noconditionaltask”,默认开启,它对N-Way Join会做优化,枚举所有N-1表size总和,判断是否小于参数hive.auto.convert.join.noconditionaltask.size(默认10MB),如果小于该值,则会自动转化成Map-Side Join,将N-1张表HashTable打包DistributedCache上传至HDFS分发至各Task节点和Factor Table做Join,从而避免了通常Reduce-side Join会起N-1个MR Job的开销,但是这个参数还是显得过于乐观了,不同于之前的Map Join优化策略(hive.auto.convert.join),它在替换了conditional task后,没有相应的common-join backup task,从而一旦由于某种原因MapRedLocalTask fail,就会导致整个Job fail, 而0.9中会起backup task来做alternative,所以从Job Level看还是正确执行的,只是执行时间变长了。为保证语句执行的正确性,我们默认关闭此优化参数。
hive.auto.convert.join.noconditionaltask.size:
多个mapjoin转换为1个时,所有小表的文件大小总和的最大值。

例如,一个大表顺序关联3个小表a(10M), b(8M),c(12M),如果hive.auto.convert.join.noconditionaltask.size的值:
1. 小于18M,则无法合并mapjoin,必须执行3个mapjoin;2. 大于18M小于30M,则可以合并a和b表的mapjoin,所以只需要执行2个mapjoin;3. 大于30M,则可以将3个mapjoin都合并为1个。
合并mapjoin有啥好处呢?因为每个mapjoin都要执行一次map,需要读写一次数据,所以多个mapjoin就要做多次的数据读写,合并mapjoin后只用读写一次,自然能大大加快速度。但是执行map是内存大小是有限制的,在一次map里对多个小表做mapjoin就必须把多个小表都加入内存,为了防止内存溢出,所以加了hive.auto.convert.join.noconditionaltask.size参数来做限制。不过,这个值只是限制输入的表文件的大小,并不代表实际mapjoin时hashtable的大小。 
我们可以通过explain查看执行计划,来看看mapjoin是否生效。


*****************************************************************************************************************

hive.script.auto.progress
:默认false。hive的transform/map/reduce脚本执行时是否自动的将进度信息发送给TaskTracker来避免任务没有响应被误杀,本来是当脚本输出到标准错误时,发送进度信息,但是开启该项后,输出到标准错误也不会导致信息发送,因此有可能会造成脚本有死循环产生,但是TaskTracker却没有检查到从而一直循环下去;
hive.script.serde
用户脚本转换输入到输出时的SerDe约束,默认是org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe;
hive.binary.record.max.length:默认1000,。从一个二进制流读取和对待每一hive.binary.record.max.length字节作为记录。在流的结尾可以有小于hive.binary.record.max.length字节最后一个记录
hive.server2.max.start.attempts: 默认30,感觉没啥用,应该是HiveServer2退出前,每60秒尝试重启一次,持续30分钟。
hive.server2.transport.mode :
 默认值为binary(TCP),可选值HTTP。
hive.server2.thrift.http.port:
HTTP的监听端口,默认值为10001。
hive.server2.thrift.http.path :
 服务的端点名称,默认为 cliservice。
hive.server2.thrift.http.min.worker.threads:
 服务池中的最小工作线程,默认为5。 
hive.server2.thrift.http.max.worker.threads:
 服务池中的最小工作线程,默认为500。
hive.script.recordreader:
从脚本读数据的时候的默认reader,默认是org.apache.hadoop.hive.ql.exec.TextRecordReader;
stream.stderr.reporter.prefix:默认‘reporter: ‘。感觉没啥用, 加此前缀可在标准的Streaming jobs的日志中记录计数器和标准信息
stream.stderr.reporter.enabled:默认true。 应该是streaming job时展现streaing的工作状态和技术信息。
hive.script.recordwriter:
写数据到脚本时的默认writer,默认org.apache.hadoop.hive.ql.exec.TextRecordWriter;
hive.input.format
:输入格式,默认是org.apache.hadoop.hive.ql.io.CombineHiveInputFormat,如果出现问题,可以改用org.apache.hadoop.hive.ql.io.HiveInputFormat; 这个你们应该熟悉哦
hive.udtf.auto.progress:
UDTF执行时hive是否发送进度信息到TaskTracker,默认是false;
hive.mapred.reduce.tasks.speculative.execution:
reduce任务推测执行是否开启,默认是true;
hive.exec.counters.pull.interval:
运行中job轮询JobTracker的时间间隔,设置小会影响JobTracker的load,设置大可能看不出运行任务的信息,要去平衡,默认是1000;
hive.querylog.location:集群值是:/tmp/${user.name} 。 hive运行时日志文件的位置。
hive.querylog.enable.plan.progress:默认true。
每次检查作业的进度时是否记录计划的进度到日志中。这些日志保存在hive.querylog.location指定的位置(Hive-0.10版本开始)。
hive.querylog.plan.progress.interval:默认:60000。记录计划执行进度的时间间隔,单位是毫秒。如果map或者reduce的进度有整数百分比的变化,则不考虑该值而该进度被记入日志。
hive.enforce.bucketing:
数据分桶是否被强制执行,默认false,如果开启,则写入table数据时会启动分桶。
hive.enforce.sorting:
开启强制排序时,插数据到表中会进行强制排序,默认false;
hive.optimize.bucketingsorting:默认true。 百度翻译没看懂。。。。
If hive.enforce.bucketing or hive.enforce.sorting is true, dont create a reducer for enforcing
bucketing/sorting for queries of the form:
insert overwrite table T2 select * from T1;
where T1 and T2 are bucketed/sorted by the same keys into the same number of buckets.
你们可以看看。。。。
hive.enforce.sortmergebucketmapjoin: 默认false 。不懂。。。。
hive.auto.convert.sortmerge.join:默认false。应该是如果联接表通过sort-merge join的标准,将自动转换为一个sort-merge join。
h
ive.auto.convert.sortmerge.join.bigtable.selection.policy
默认:org.apache.hadoop.hive.ql.optimizer.AvgPartitionSizeBasedBigTableSelectorForAutoSMJ
这个字太多。看图吧。。。。。。
Hive调优技巧汇总

hive.auto.convert.sortmerge.join.to.mapjoin:默认false,英文描述很无助。。。。。。。。。。。。。
hive.metastore.ds.connection.url.hook:
查找JDO连接url时hook的名字,默认是javax.jdo.option.ConnectionURL;
hive.metastore.ds.retry.attempts:
当出现连接错误时重试连接的次数,默认是1次;
hive.metastore.ds.retry.interval:
metastore重试连接的间隔时间,默认1000毫秒;
hive.metastore.server.min.threads:
在thrift服务池中最小的工作线程数,默认是200;
hive.metastore.server.max.threads:
最大线程数,默认是100000;
hive.metastore.server.tcp.keepalive:
metastore的server是否开启长连接,长连可以预防半连接的积累,默认是true;
hive.metastore.sasl.enabled:
metastore thrift接口的安全策略,开启则用SASL加密接口,客户端必须要用Kerberos机制鉴权,默认是不开启false;
hive.metastore.thrift.framed.transport.enabled:默认false,大概是用标准的TTransport 。如果是true,
metastore thrift接口将会使用TFramedTransport。
hive.metastore.kerberos.keytab.file:
在开启sasl后kerberos的keytab文件存放路径,默认是空;
hive.metastore.kerberos.principal:
kerberos的principal,_HOST部分会动态替换,默认是hive-metastore/_HOST@EXAMPLE.COM;
hive.cluster.delegation.token.store.class:
代理token的存储实现类,默认是org.apache.hadoop.hive.thrift.MemoryTokenStore,可以设置为org.apache.hadoop.hive.thrift.ZooKeeperTokenStore来做负载均衡集群;
hive.cluster.delegation.token.store.zookeeper.connectString:
zk的token存储连接串,默认是localhost:2181;
hive.cluster.delegation.token.store.zookeeper.znode:
token存储的节点跟路径,默认是/hive/cluster/delegation;
hive.cluster.delegation.token.store.zookeeper.acl:
token存储的ACL,默认是sasl:hive/host1@example.com:cdrwa,sasl:hive/host2@example.com:cdrwa;
hive.metastore.cache.pinobjtypes:
在cache中支持的metastore的对象类型,由逗号分隔,默认是Table,StorageDescriptor,SerDeInfo,Partition,Database,Type,FieldSchema,Order;
hive.optimize.reducededuplication:
如果数据已经根据相同的key做好聚合,那么去除掉多余的map/reduce作业,此配置是文档的推荐配置,建议打开,默认是true;
hive.optimize.correlation : 默认false。利用内部查询的相关性。不明白。。。。exploit intra-query correlations.
hive.optimize.reducededuplication.min.reducer:默认是4. 看不懂。。。。。

******************************动态分区参数******************************************
hive.exec.dynamic.partition:
在DML/DDL中是否支持动态分区,默认false;
hive.exec.dynamic.partition.mode:
默认strict,在strict模式下,动态分区的使用必须在一个静态分区确认的情况下,其他分区可以是动态;
hive.exec.max.dynamic.partitions:
动态分区的上限,默认1000;
hive.exec.max.dynamic.partitions.pernode:
每个mapper/reducer节点可以创建的最大动态分区数,默认100;
hive.exec.default.partition.name:
当动态分区启用时,如果数据列里包含null或者空字符串的话,数据会被插入到这个分区,默认名字是__HIVE_DEFAULT_PARTITION__;
******************************************************************************************
hive.exec.max.created.files:
一个mapreduce作业能创建的HDFS文件最大数,默认是100000;
hive.stats.dbclass:
存储hive临时统计信息的数据库,默认是jdbc:derby;
hive.stats.autogather:
在insert overwrite命令时自动收集统计信息,默认开启true;
hive.stats.jdbcdriver:
数据库临时存储hive统计信息的jdbc驱动;
hive.stats.dbconnectionstring:
临时统计信息数据库连接串,默认jdbc:derby:databaseName=TempStatsStore;create=true;
hive.stats.defaults.publisher:
如果dbclass不是jdbc或者hbase,那么使用这个作为默认发布,必须实现StatsPublisher接口,默认是空;
hive.stats.jdbc.timeout:
jdbc连接超时配置,默认30秒;
hive.stats.retries.max:
当统计发布合聚集在更新数据库时出现异常时最大的重试次数,默认是0,不重试;
hive.stats.retries.wait:
重试次数之间的等待窗口,默认是3000毫秒;
hive.stats.reliable:默认是false,翻译是,无论查询是否失败。统计数据不能完全准确的收集;如果设置成true,reading/writing from/into一个分区都可能会失败,因为数据无法准确计算。(这个应该是跟踪问题的时用的参数。。。)
hive.stats.collect.tablekeys:默认false。英文看不到太懂。应该是无论是join或者group by 的keys 都是由执行计划生成和维护的。。。这个有用的访问识别表是否应该被分桶。。。好吧。很乱。
hive.stats.collect.scancols:默认false。应该是执行计划中跟踪列的访问,在表的访问中减少无用的列。
hive.stats.ndv.error:默认20.0。百分比表示的标准误差。提供了一个精度和计算成本之间的权衡,一个较低的值的错误指示更高的精度和更高的计算成本。 (我的理解是默认值低了,错误的指示就高了,但是计算成本也高了)。
hive.stats.key.prefix.max.length:默认200。 翻译看不明白。。。。
hive.support.concurrency:
hive是否支持并发,默认是false,支持读写锁的话,必须要起zookeeper;
hive.lock.numretries:
获取锁时尝试的重试次数,默认是100;
hive.unlock.numretries:
获取解锁时尝试的重试次数,默认是100;
hive.lock.sleep.between.retries:
在重试间隔的睡眠时间,默认60秒;
hive.zookeeper.quorum:
zk地址列表,默认是空;
hive.zookeeper.client.port:
zk服务器的连接端口,默认是2181;
hive.zookeeper.session.timeout:
zk客户端的session超时时间,默认是600000;
hive.zookeeper.namespace:
在所有zk节点创建后的父节点,默认是hive_zookeeper_namespace;
hive.zookeeper.clean.extra.nodes:
在session结束时清除所有额外node;
fs.har.impl:
访问Hadoop Archives的实现类,低于hadoop 0.20版本的都不兼容,默认是org.apache.hadoop.hive.shims.HiveHarFileSystem;
hive.archive.enabled:
是否允许归档操作,默认是false;
hive.fetch.output.serde:
FetchTask序列化fetch输出时需要的SerDe,默认是org.apache.hadoop.hive.serde2.DelimitedJSONSerDe;
hive.exec.mode.local.auto:
是否由hive决定自动在local模式下运行,默认是false;
hive.exec.drop.ignorenoneexistent:
在drop表或者视图时如果发现表或视图不存在,是否报错,默认是true;
hive.exec.show.job.failure.debug.info:
在作业失败时是否提供一个任务debug信息,默认true;
hive.auto.progress.timeout:
运行自动progressor的时间间隔,默认是0等价于forever;

<!– HBase Storage Handler Parameters –> HBase存储处理器参数

hive.hbase.wal.enabled:
写入hbase时是否强制写wal日志,默认是true;
hive.table.parameters.default:
新建表的属性字段默认值,默认是empty空;
hive.entity.separator:用于构造表和分区的名称的分隔符。例如,@
tablename@partitionname
hive.ddl.createtablelike.properties.whitelist:当执行创建表时,要复制的表属性。默认是空;
hive.variable.substitute:
是否支持变量替换,如果开启的话,支持语法如${var} ${system:var}和${env.var},默认是true;
hive.variable.substitute.depth:默认40。字面翻译替换引擎的最大替换。
hive.conf.validation:默认ture。应该是是否检查注册的hive配置的类型。
hive.security.authorization.enabled:
hive客户端是否认证,默认是false;
hive.security.authorization.manager:
hive客户端认证的管理类,默认是org.apache.hadoop.hive.ql.security.authorization.DefaultHiveAuthorizationProvider;用户定义的要实现org.apache.hadoop.hive.ql.security.authorization.HiveAuthorizationProvider;
hive.security.metastore.authorization.manager
:metastore的认证管理类,默认是org.apache.hadoop.hive.ql.security.authorization.DefaultHiveMetastoreAuthorizationProvider;用户定义的必须实现org.apache.hadoop.hive.ql.security.authorization.HiveMetastoreAuthorizationProvider接口;接口参数要包含org.apache.hadoop.hive.ql.security.authorization.StorageBasedAuthorizationProvider接口;使用HDFS的权限控制认证而不是hive的基于grant的方式;
hive.security.authenticator.manager
:hive客户端授权的管理类,默认是org.apache.hadoop.hive.ql.security.HadoopDefaultAuthenticator;用户定义的需要实现org.apache.hadoop.hive.ql.security.HiveAuthenticatorProvider;
hive.security.metastore.authenticator.manager:
metastore端的授权管理类,默认是org.apache.hadoop.hive.ql.security.HadoopDefaultMetastoreAuthenticator,自定义的必须实现org.apache.hadoop.hive.ql.security.HiveAuthenticatorProvider接口;
hive.security.authorization.createtable.user.grants:
当表创建时自动授权给用户,默认是空;
hive.security.authorization.createtable.group.grants:
同上,自动授权给组,默认是空;
hive.security.authorization.createtable.role.grants:
同上,自动授权给角色,默认是空;
hive.security.authorization.createtable.owner.grants:
同上,自动授权给owner,默认是空;
hive.security.command.whitelist:hive授权用户执行的SQL命令列表,用都好分隔。默认是set,reset,dfs,add,delete;
hive.conf.restricted.list:运行时的不可变配置列表,逗号分隔。默认是空;
hive.metastore.authorization.storage.checks:
在做类似drop partition操作时,metastore是否要认证权限,默认是false;
hive.error.on.empty.partition:
在遇到结果为空的动态分区时是否报错,默认是false;
hive.index.compact.file.ignore.hdfs:
在索引文件中存储的hdfs地址将在运行时被忽略,如果开启的话;如果数据被迁移,那么索引文件依然可用,默认是false;
hive.optimize.index.filter.compact.minsize:
压缩索引自动应用的最小输入大小,默认是5368709120;
hive.optimize.index.filter.compact.maxsize:
同上,相反含义,如果是负值代表正无穷,默认是-1;
hive.index.compact.query.max.size:
一个使用压缩索引做的查询能取到的最大数据量,默认是10737418240 个byte;负值代表无穷大;
hive.index.compact.query.max.entries:
使用压缩索引查询时能读到的最大索引项数,默认是10000000;负值代表无穷大;
hive.index.compact.binary.search:
在索引表中是否开启二分搜索进行索引项查询,默认是true;
hive.exim.uri.scheme.whitelist:
在导入导出数据时提供的一个白名单列表,列表项之间由逗号分隔,默认hdfs,pfile;
hive.lock.mapred.only.operation:
控制是否在查询时加锁,默认是false;

**************************************LIMIT参数**************************************
hive.limit.row.max.size:
字面意思理解就是在使用limit做数据的子集查询时保证的最小行数据量,默认是100000;
hive.limit.optimize.limit.file:
使用简单limit查询数据子集时,可抽样的最大文件数,默认是10;
hive.limit.optimize.enable:
使用简单limit抽样数据时是否开启优化选项,默认是false,关于limit的优化问题,在hive programming书中解释的是这个feature有drawback,对于抽样的不确定性给出了风险提示;
hive.limit.optimize.fetch.max:
使用简单limit抽样数据允许的最大行数,默认50000,查询query受限,insert不受影响;
hive.limit.pushdown.memory.usage:默认0.3f。 应该是查询分配给hash RS算子最大内存;
hive.rework.mapredwork:
是否重做mapreduce,默认是false;
hive.exec.concatenate.check.index:
如果设置为true,那么在做ALTER TABLE tbl_name CONCATENATE on a table/partition(有索引) 操作时,抛出错误;可以帮助用户避免index的删除和重建;
hive.sample.seednumber:
用来区分抽样的数字,默认是0;
hive.io.exception.handlers:
io异常处理handler类列表,默认是空,当record reader发生io异常时,由这些handler来处理异常;
hive.transform.escape.input:默认false。 这个参数避免了特殊字符(换行符、回车符和标签)被传递给用户脚本时带来的影响。这可以然后hive表里包含含特俗字符的数据。
hive.exec.rcfile.use.explicit.header:默认为ture。应该是跟文件的格式有关
hive.exec.orc.dictionary.key.size.threshold:默认0.8。应该是如果在字典中的键数比例大于此部分的非空行总数,则关闭字典编码。1是默认一直使用字典编码。
hive.multi.insert.move.tasks.share.dependencies:默认false。不是太懂。如果这个参数被设置,多插入查询在结束前只会执行一次。优点:一旦启用并发,一旦查询完成
hive.server2.async.exec.wait.queue.size:默认100。在HiveServer2异步线程池等待队列的大小。打这个限制后,异步线程池会拒绝新的请求。
hive.server2.thrift.port:默认10000。HiveServer2 Thrift接口的端口号。可以通过设置$HIVE_SERVER2_THRIFT_PORT重写。
hive.server2.thrift.bind.host:绑定主机上运行HiveServer2 Thrift接口的端口。可以通过设置$hive_server2_thrift_bind_host重写。该值默认为localhost,如果需要在其它机器远程访问Hive,则需要将它改成IP地址。
hive.server2.authentication:授权模式,默认NONE,可选的包括NOSASL、KERBEROS、LDAP、PAM和CUSTOM等授权模式。
客户端身份验证类型:
NONE:没有验证检查
LDAP:LDAP / AD认证
Kerberos:Kerberos/GSSAPI认证
自定义:自定义身份验证提供程序(使用hive.server2.custom.authentication.class的属性)
hive.server2.custom.authentication.class:
用户授权类,实现org.apache.hive.service.auth.PasswdAuthenticationProvider接口
hive.server2.authentication.kerberos.principal:Kerberos主服务器。默认空。
hive.server2.authentication.kerberos.keytab:
服务principal的keytab。默认空。
hive.server2.authentication.ldap.url:
LDAP的URL。默认空。
hive.server2.authentication.ldap.baseDN:
基于DN的LDAP。默认空。
hive.server2.enable.doAs:
匿名连接用户,默认true。
hive.server2.table.type.mapping:默认CLASSIC。应该是此设置反映了HiveServer如何向JDBC和其他客户端提供表的类型,实现可用表和表类型的检索。
HIVE:显示hive自带的表类型managed_table,external_table,virtual_view。
CLASSIC:更一般类型,如表和视图。
hive.server2.thrift.sasl.qop:SASL QOP值;设置为下列值使更高水平的客户通信保护Hive Server2。
“auth” – 国际认证和完整性保护(默认)
“auth-int” – 身份验证和完整性保护
“auth-conf” -身份验证和完整性和机密性保护
这个只支持在Kerberos作为HS2客户端的授权

关于hive server2的配置可以参考网络资料:


hive.metastore.schema.verification:默认是true。意思是:(强制metastore的schema一致性,开启的话会校验在metastore中存储的信息的版本和hive的jar包中的版本一致性,并且关闭自动schema迁移,用户必须手动的升级hive并且迁移schema,关闭的话只会在版本不一致时给出警告。)
这个参数在网上查好像是解决由于hive版本引发的问题时候回改为false。由于第一次启动metastore服务时,mysql作为数据源的hive数据库内没有生成任何表和数据,所以会出现返回的版本号为空的情况。我们可以暂时在hive.metastore.schema.verification里设置成false,在第一次启动自动生成了数据后,那么就可以将这个配置值再改回true,往后也相关无事了。
hive.plan.serialization.format:客户端和任务节点之间的查询计划格式。支持两个参数:kryo和JAVAXML。kryo是默认。
hive.server2.allow.user.substitution:默认为true。应该是允许altername 用户被指定为打开一部分HiveServer2的连接请求。

  • 压缩
a. 
set hive.exec.compress.intermediate=true;
set mapred.map.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
解释:如果集群具有很好的CPU性能,但是网络带宽有限,这两个属性可以加速中间结果的交换。(如果集群具有很高的网络io延迟,那么这个选项应该被打开)
测试:

Q22
Q23
Q24
未压缩
2m9.787s
14m19.011s
4m41.635s
压缩
2m22.371s
13m57.379s
4m43.945s
结论:性能未见明显提升

b.
set hive.exec.compress.output=false;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.DefaultCodec;
解释:默认是使得创建的结果表是否进行压缩,关系到可读性


Q22
Q23
Q24
未压缩
2m9.787s
14m19.011s
4m41.635s

压缩
2m14.084s
13m48.921s
4m40.755s

结论: 
性能未见明显提升


c.
set hive.default.fileformat=TextFile;
解释:默认文件类型,未测试,应该影响不大。

  • Mapper settings
a.

set mapred.max.split.size=67108864;

set mapred.min.split.size=1;
解释:一个hive表包含的物理文件的数量与hive预测启动多少mapper数量无关,因为hive使用HiveCombineInputFormat来合并文件。上面两个参数是最能影响hive预测生成的mapper数量的,降低这些值会导致过多的map task,太高会导致过少的map task,系统利用率不高。两个极端都会影响性能。对于小数据集(1-100G),128M可能是个好的值。作为预测的话,使用中等表的大小除以想要利用的集群的map task数量。

10G Data:


Q22
Q23
Q24
8388608 (8MB)

1m40.767s
9m54.701s
4m54.342s
16777216 (16MB)

1m44.801s
10m45.015s
4m41.974s
33554432 (32MB)

2m0.222s
12m43.198s
4m36.464s
67108864 (64MB)
2m9.787s
14m19.011s
4m41.635s

134217728 (128MB)
2m51.450s
16m3.758s
4m43.410s

结论:
10G Data, Q22/Q23 随着mapred.max.split.size的减小而性能提升,Q24无明显性能提升

  • Reducer Settings
a.

set hive.exec.reducers.bytes.per.reducer=256000000;

解释:每个reducer处理的数据大小,如果input size是10G, 设置为1G,那么就会启动10个reducer

10G Data:


Q22
Q23
Q24
128000000
2m7.526s
13m44.007s
4m42.296s
256000000
2m9.787s
14m19.011s
4m41.635s

512000000
2m7.969s
13m45.184s
4m39.975s
结论:
性能未见明显提升

b.
set hive.exec.reducers.max=99999;
解释:可以使用的最大的reducer的数量,如果配置的是负值,hive将会使用999作为可以使用的最大的reducer数量。
结论:
从日志看,reducer数量远小于999,因此配置这个对性能影响应该不会太大。

  • join

a.

set hive.auto.convert.join=true;

解释: hive是否会根据输入文件大小将普通的join转为mapjoin,默认是true
测试:

Q22
Q23
Q24
True
2m9.787s
14m19.011s
4m41.635s

False
9m44.347s
45m1.006s
5m23.501s

结论:
Enable这个属性能够显著提高性能。


b.
set hive.auto.convert.join.noconditionaltask = true;set hive.auto.convert.join.noconditionaltask.size = 10000000;
解释:hive.auto.convert.join.noconditionaltask.size表明可以转化为MapJoin的表的大小总合。例如有A、B两个表,他们的大小都小于该属性值,那么他们都会都会分别被转化为MapJoin,如果两个表大小总和加起来也小于该属性值,那么这两个表会被合并为一个MapJoin。
测试:
1. 
set hive.auto.convert.join=false;
set hive.auto.convert.join.noconditionaltask = true;
Q22
Q23
Q24
9m22.254s
44m56.032s
5m26.398s

2. 

set hive.auto.convert.join=True;

set hive.auto.convert.join.noconditionaltask=false;

Q22
Q23
Q24
9m5.161s
18m6.333s
4m45.650s

3.

set hive.auto.convert.join=True;

set hive.auto.convert.join.noconditionaltask=True;
set hive.auto.convert.join.noconditionaltask.size=10000;



Q22
Q23
Q24
10000 (10K)
9m17.021s
16m8.071s
4m46.207s
10000000 (10M Default)
2m11.891s
13m38.050s
4m33.742s
100000000 (100M)
1m34.005s
10m43.252s
4m39.885s
1000000000 (1G)
1m30.704s
10m49.992s
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
        at org.apache.log4j.spi.LoggingEvent.<init>(LoggingEvent.java:165)
        at org.apache.log4j.Category.forcedLog(Category.java:391)
        at org.apache.log4j.Category.log(Category.java:856)
        at org.apache.commons.logging.impl.Log4JLogger.error(Log4JLogger.java:229)
        at org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask.executeInProcess(MapredLocalTask.java:349)
        at org.apache.hadoop.hive.ql.exec.mr.ExecDriver.main(ExecDriver.java:744)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.apache.hadoop.util.RunJar.main(RunJar.java:212)
Execution failed with exit status: 1
Obtaining error information
Task failed!
1000000000 (1G)

export HADOOP_CLIENT_OPTS=”-Xmx2g”
1m35.893s
10m45.741s
10m26.837s

结论:

1) 
hive.auto.convert.join会覆盖hive.auto.convert.join.noconditionaltask

2)
第二个测试说明需要将两个都设为True
3) 
hive.auto.convert.join.noconditionaltask.size应该设置的较大一点

4 )  
Job 数目变少了



set hive.mapjoin.localtask.max.memory.usage=0.90;
解释:该属性值表示本地任务将key/value保存在内存中的hash table中需要占用多少内存,如果Local任务的内存使用比这个数值大,任务则会终止,这意味着小的hive表中的数据由于太多了而不能保存在内存中。默认值是0.9.
结论:
该属性对性能没有多少影响


set hive.optimize.mapjoin.mapreduce=true;
解释:该属性决定一个Map-only任务是否会被合并到后续的Map-reduce任务中。但是,HIVE-4827对此做了改进,它不管该属性是True还是False,都会将Map-only任务合并到后续的map-reduce任务中,因此这个属性对性能影响不大。
测试:


Q22
Q23
Q24
Undefined
2m9.787s
14m19.011s
4m41.635s

True
Query returned non-zero code: 1, cause: hive configuration hive.optimize.mapjoin.mapreduce does not exists.


结论: 
出错




set hive.mapred.local.mem=1024;
解释:本地模式下,mapper和reducer的内存,默认为0
测试:


Q22
Q23
Q24
0
2m9.787s
14m19.011s
4m41.635s

1024
2m11.625s
13m41.085s
4m39.853s

结论:
性能未见明显提升




  • SMB Map Join
set hive.auto.convert.sortmerge.join=true;

set hive.auto.convert.sortmerge.join.noconditionaltask=true; //此属性不存在

set hive.optimize.bucketmapjoin = true; 
set hive.optimize.bucketmapjoin.sortedmerge = true;
解释:
Sort-Merge-Bucket (SMB) joins可以被转化为SMB Map Join。这种join归结于将已排好序的表进行合并,使得该操作比传统的map join更加快速。但是如果表是划分表,速度会慢上一些,因为每一个mapper都需要获取一个划分的一小块,这些小块具有一个单一的key。
测试:


Q22
Q23
Q24
Origin
2m9.787s
14m19.011s
4m41.635s

After
2m12.891s
13m50.629s
4m39.853s

结论:
性能未见明显提升


  • Skewjoin

hive.optimize.skewjoin=false

hive.optimize.skewjoin.compiletime=false
测试:



Q22
Q23
Q24
Origin
2m9.787s
14m19.011s
4m41.635s

After
FAILED: ParseException line 2:4 missing KW_ROLE at ‘hive’ near ‘hive’
line 2:8 missing EOF at ‘.’ near ‘hive’



hive.groupby.skewindata=false

解释:优化group by子句是否在数据中有偏差
测试:

Q22
Q23
Q24
False
2m9.787s
14m19.011s
4m41.635s

True
2m48.965s
17m2.289s
5m59.542s

结论:
性能显著下降


  • 并行

hive.exec.parallel=false

hive.exec.parallel.thread.number=8

解释:是否并行的执行job以及并行执行job的最大数量


测试:


Q22
Q23
Q24
False
2m9.787s
14m19.011s
4m41.635s

True
2m16.959s
9m32.682s
3m12.682s

结论:
Q23/Q24性能显著提升,Q22未见明显提升


  • 其他

hive.optimize.ppd=true

hive.optimize.ppd.storage=true

解释:是否enable预测pushdown,以及是否将预测pushdown到存储器。

测试:

Q22
Q23
Q24
False
2m9.787s
14m19.011s
4m41.635s

True
2m13.427s
14m7.106s
4m50.376s

结论:
性能未见明显提升


hive.optimize.index.filter=false
解释:是否自动使用索引
测试:

Q22
Q23
Q24
False
2m9.787s
14m19.011s
4m41.635s

True
2m15.132s
14m10.505s
4m49.860s

结论:
性能未见明显提升



hive.mapjoin.smalltable.filesize=5000000
解释:小表文件大小的阈值,如果表大小小于该阈值,则会将普通join转化为map join。
测试:

Q22
Q23
Q24
1M
2m17.173s
14m11.657s
4m57.931s
5M
2m9.787s
14m19.011s
4m41.635s

10M
2m15.576s
14m20.439s
5m0.655s

结论:
性能未见明显提升


  • 综合性能提升配置:
set mapred.max.split.size=8388608;
set hive.auto.convert.join=True;

set hive.auto.convert.join.noconditionaltask=
True
;
set hive.auto.convert.join.noconditionaltask.size=100000000 ;
set hive.groupby.skewindata=
false

set hive.exec.parallel=
True
set hive.exec.parallel.thread.number=8

10G Data:


Q22
Q23
Q24
Origin
2m9.787s
14m19.011s
4m41.635s

After
1m20.856s (37.7% up)
7m22.865s (48.4% up)
3m42.101s (21.1 % up)


1T Data:


Q22
Q23
Q24
Origin
20m8.207s
24m50.490s
12m47.515s


hive.auto.convert.join.noconditionaltask.size=100000000 ;


Q22
Q23
Q24
8388608 (8MB)
10m57.554s

40+m 
(
skip
)

16777216 (16MB)

7m27.275s
40+m
(skip)

33554432 (32MB)

6m9.236s
36m27.416s
(skip)
67108864 (64MB default)
5m36.872s
31m55.655s
远大于12min
134217728 (128MB)
4m49.397s
29m44.575s
20m17.109s
268435456 (256MB)
5m43.634
skip
skip


set mapred.max.split.size=
134217728 
;

hive.auto.convert.join.noconditionaltask.size=
; (export HADOOP_CLIENT_OPTS=”-Xmx2g”)





Q22
Q23
Q24
10M(default)
40min+


100M
4m49.397s
29m44.575s
20m17.109s

500M
4m57.060s
29min左右
同上
1G (export HADOOP_CLIENT_OPTS=”-Xmx2g”)
4m56.741s
29min左右
同上


1T Data配置:
set mapred.max.split.size=134217728 ;
set hive.auto.convert.join=True;

set hive.auto.convert.join.noconditionaltask=
True
;
set hive.auto.convert.join.noconditionaltask.size=100000000 ;
set hive.groupby.skewindata=
false

set hive.exec.parallel=
True
set hive.exec.parallel.thread.number=8


ps: 集群越来越慢,在最初的配置下rerun跟上面的配置进行对比:


Q22
Q23
Q24
Origin
44m56.835s
45m18.217s
34m43.947s
After
4m49.397s
29m44.575s

20m17.109s

Q22在此配置下有接近10/11性能提升


重启集群之后,rerun:

Q22
Q23
Q24
Origin
23m7.372s
26m49.460s
15m57.590s
After
2m31.808 (89% up)
18m18.278s (31.8% up)
12m55.900s (19.0% up)

Map Reduce数量相关

数据分片大小 (分片的数量决定map的数量) 
计算公式: splitSize = Math.max(minSize, Math.min(maxSize, blockSize))

 
  • 1
  • 2
  • 3

set mapreduce.input.fileinputformat.split.maxsize=750000000;

单个reduce处理的数据量 (影响reduce的数量) 
计算公式: Max(1, Min(hive.exec.reducers.max [1099], ReducerStage estimate/hive.exec.reducers.bytes.per.reducer)) x hive.tez.max.partition.factor

 
  • 1
  • 2
  • 3

set hive.exec.reducers.bytes.per.reducer=629145600;

tez将会根据vertice的输出大小动态预估调整reduce的个数

 
  • 1
  • 2

set hive.tez.auto.reducer.parallelism = true; 
执行计划相关

hive执行引擎 mr/tez/spark

 
  • 1
  • 2

set hive.execution.engine=mr;

调整Join顺序,让多次Join产生的中间数据尽可能小,选择不同的Join策略

 
  • 1
  • 2

set hive.cbo.enable=true;

如果数据已经根据相同的key做好聚合,那么去除掉多余的map/reduce作业

 
  • 1
  • 2

set hive.optimize.reducededuplication=true;

如果一个简单查询只包括一个group by和order by,此处可以设置为1或2

 
  • 1
  • 2

set hive.optimize.reducededuplication.min.reducer=4;

Map Join优化, 不太大的表直接通过map过程做join

 
  • 1
  • 2

set hive.auto.convert.join=true; 
set hive.auto.convert.join.noconditionaltask=true;

Map Join任务HashMap中key对应value数量

 
  • 1
  • 2

set hive.smbjoin.cache.rows=10000;

可以被转化为HashMap放入内存的表的大小(官方推荐853M)

 
  • 1
  • 2

set hive.auto.convert.join.noconditionaltask.size=894435328;

map端聚合(跟group by有关), 如果开启, Hive将会在map端做第一级的聚合, 会用更多的内存 
http://dmtolpeko.com/2014/10/13/map-side-aggregation-in-hive/

开启这个参数 sum(1)会有类型转换问题

 
  • 1
  • 2
  • 3
  • 4
  • 5

set hive.map.aggr=false;

所有map任务可以用作Hashtable的内存百分比, 如果OOM, 调小这个参数(官方默认0.5)

 
  • 1
  • 2

set hive.map.aggr.hash.percentmemory=0.5;

将只有SELECT, FILTER, LIMIT转化为FETCH, 减少等待时间

 
  • 1
  • 2

set hive.fetch.task.conversion=more; 
set hive.fetch.task.conversion.threshold=1073741824;

聚合查询是否转化为FETCH

 
  • 1
  • 2

set hive.fetch.task.aggr=false;

如果数据按照join的key分桶,hive将简单优化inner join(官方推荐关闭)

 
  • 1
  • 2

set hive.optimize.bucketmapjoin= false; 
set hive.optimize.bucketmapjoin.sortedmerge=false;

向量化计算 
https://cwiki.apache.org/confluence/display/Hive/Vectorized+Query+Execution 
如果开启, sum(if(a=1,1,0))这样的语句跑不过

 
  • 1
  • 2
  • 3
  • 4

set hive.vectorized.execution.enabled=false; 
set hive.vectorized.execution.reduce.enabled=false; 
set hive.vectorized.groupby.checkinterval=4096; 
set hive.vectorized.groupby.flush.percent=0.1; 
动态分区相关

hive0.13有个bug, 开启这个配置会对所有字段排序

 
  • 1
  • 2

set hive.optimize.sort.dynamic.partition=false;

以下两个参数用于开启动态分区

 
  • 1
  • 2

set hive.exec.dynamic.partition=true; 
set hive.exec.dynamic.partition.mode=nonstrict;

小文件相关

合并小文件

 
  • 1
  • 2

set hive.merge.mapfiles=true; 
set hive.merge.mapredfiles=true; 
set hive.merge.tezfiles=true; 
set hive.merge.sparkfiles=false; 
set hive.merge.size.per.task=536870912; 
set hive.merge.smallfiles.avgsize=536870912; 
set hive.merge.orcfile.stripe.level=true; 
ORC相关

https://orc.apache.org/docs/hive-config.html

如果开启将会在ORC文件中记录metadata

 
  • 1
  • 2

set hive.orc.splits.include.file.footer=false;

ORC写缓冲大小

 
  • 1
  • 2

set hive.exec.orc.default.stripe.size=67108864; 
统计相关

新创建的表/分区是否自动计算统计数据

 
  • 1
  • 2

set hive.stats.autogather=true; 
set hive.compute.query.using.stats=true; 
set hive.stats.fetch.column.stats=true; 
set hive.stats.fetch.partition.stats=true;

手动统计已经存在的表

 
  • 1
  • 2

ANALYZE TABLE COMPUTE STATISTICS; 
ANALYZE TABLE COMPUTE STATISTICS for COLUMNS; 
ANALYZE TABLE partition (coll=”x”) COMPUTE STATISTICS for COLUMNS; 
其他

在order by limit查询中分配给存储Top K的内存为10%

 
  • 1
  • 2

set hive.limit.pushdown.memory.usage=0.1;

是否开启自动使用索引

 
  • 1
  • 2

set hive.optimize.index.filter=true;

获取文件块路径的工作线程数

 
  • 1
  • 2

set mapreduce.input.fileinputformat.list-status.num-threads=5;

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/14391.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!