hive查询小文件多的为什么会慢
‘壹’ Hive执行简单查询,耗时巨长,是什么情况
1. 查询语言。由于 SQL 被广泛的应用在数据仓库中,因此,专门针对 Hive 的特性设计了类 SQL 的查询语言 HQL。熟悉 SQL 开发的开发者可以很方便的使用 Hive 进行开发。 2. 数据存储位置。Hive 是建立在 Hadoop 之上的,所有 Hive 的数据都是存储
‘贰’ 怎样去找出线上hive或maprece运行慢的原因
先通过Hadoop的WEB监控界面找到Hive或者MapRece对应的Application,然后点进去查看该Application的Map和Rece任务数,哪个阶段比较慢,再定位慢的原因。
‘叁’ 如何解决spark写hive慢的问题
dataframe.registerTempTable("result")
sql(s"""INSERT OVERWRITE Table $outputTable PARTITION (dt ='$outputDate') select * from result""")
而整个结果数据的产生只需要4分钟左右的时间,比如以下方式:将结果以textfile存入hdfs:
result.rdd.saveAsTextFile(output_tmp_dir)
由此可见,对hive的写入操作耗用了大量的时间。
对此现象的优化可以是,将文件存为符合hive table文件的格式,然后使用hive load将产生的结果文件直接move到指定目录下。代码如下:
result.rdd.map { r => r.mkString("\001") }.repartition(partitions).saveAsTextFile(output_tmp_dir)
sql(s"""load data inpath '$output_tmp_dir' overwrite into table $output partition (dt='$dt')""")
‘肆’ hive 执行查询语句时间太长 550W数据count出来 需要60多秒 还没有oracle速度快 那位大神知道问题出现在什
这个机制不一样。
在oracle中,如果你count某一列,应该是仅仅加载这一列,如果有索引啥的,直接在索引上统计了,当然很快。(如果你count varchar非常大之类的字段,速度应该会非常慢)
但是hive的cunt是基于hadoop的MR任务的,还是读取每一行的所有的数据,如果你每行中有类似于clob之类的列的话,IO的开销可想而知。 另外 MR任务的启动也是需要时间的。
另外就是和你的hadoop的数据节点多少有关。
‘伍’ hadoop分布式计算中,使用Hive查询Hbase数据慢的问题
首先,节点规模上去,或者硬件配置上去才能让hadoop引擎转起来。
配置很低,一看就知道是科技项目,或者小作坊的做法,你的需求是很不合理的。在这配置下是没优化空间。
另一方面,HIVE原理上只是基本的SQL转义,换句话说,当你云计算规模上去后,HIVE优化的本质就是让你优化SQL,而不是HIVE多强。
‘陆’ hive查询数据一直卡住,最后报错
然后删除NEXT_LOCK_ID一条记录。
NEXT_LOCK_ID 始终有锁,无法删除数据。;1、停止hiveserver2,MetaStore 服务;发现还有锁;2、查看hive应用进程 ps -ef|grep hive,全部杀掉,锁释放;3、然后删除NEXT_LOCK_ID一条记录;4、重启hiveserver2,MetaStore;5、查询hive 恢复正常。
原因可能是多个进程同时操作,导致hive事务上的bug,插进了2条一样的数据,导致元数据库被锁以下几个hive元数据表跟hive的事务有关:NEXT_LOCK_ID;next_compaction_queue_id;next_txn_id;以上三个表出问题就有可能会报以下错误: error in acquiring locks: error communicating with the metastore.hive 卡死的原因很多,这个是其中之一,基本都hive metastore会有一些关系,大家可以按这个方向去定位原因,就能更快速寻找到问题的根源。
‘柒’ hive性能优化及参数调优
记录一下自己在工作中经常用到的几个参数设置,从调整的实际效果看还是有效果的。
企业相关服务器资源配置:平均600台active的节点,
每个节点可用的内存在200G左右,可用的memory total:116T
1、**set hive.exec.parallel=true;**
开启job的并行:基本每个hql脚本都会开启这个参数,默认并行度为8,
在集群资源充足的情况下,可以提高job并行的数量:
set hive.exec.parallel.thread.number=16; (企业生产中我是很少用到这个的,都是用的默认值,因为太消耗资源怕影响别的任务,搞不好会被运维抓住,邮件通报批评!当然使用时还是看具体情况吧!)
因为需求中一张表的job的数量每次基本都在20个以上,在相关维度多,涉及到的字段逻辑复杂的情况下,
一张表中job的数量会超过100个,之前做的一个需求中insert插入的脚本中job的数量达到了169个,
在测试环境运行的时候只用了一个小时就跑完了,数据量在一亿条左右,大概有一百多G。
2、**set hive.map.aggr=true;**
在map端中会做部分聚集操作,效率更高但需要更多的内存,可以根据自己企业的资源情况来设置,
如果我的脚本涉及到的数据量不大的话,我一般不会开启这个参数。
3、**set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;**
hive0.5开始的默认值,执行map前进行小文件合并,在一个job中生成的map的数量很多的时候,
和第二个参数一起开启配合使用,在实际生产中多次验证发现可以减少一倍以上的map数量。
在开启前我的一个job的map数量有577个,开启后的map的数量只有196个,极大提高程序的运行效率。
4、**set mapred.max.split.size=256000000;**
每个Map(一个切片的)最大输入大小(这个值决定了合并后文件的数量),和第3个参数配合一起使用
默认值也是256000000,
mapred.min.split.size默认值是10000000
dfs.block.size默认是128M,这个参数通过hive来更改是没有实际用的,只能通过hdfs来修改
***实际在hive中,并不是split的大小要小于等于blocksize,而是可以远大于blocksize,为什么???(map的数量)***
<1>当hive需要处理的文件是压缩,且压缩算法不支持文件切分的时候,决定map个数的因素主要是文件块实际存储的大小,
如果文件块本身很大,比如500Mb左右,那么每个map处理的splitsize至少要是500Mb左右。
这个时候我们不能人为通过参数降低每个map的splitsize来增加map个数,只能通过增加splitsize,减少map个数,
如果hive处理的文件是压缩模式,且压缩模式不支持文件切分,那么这个时候我们只能通过控制参数来减少map个数,而不能通过配置参数来增加map个数,所以Hive对于压缩不可切分文件的调优有限
<2>如果Hive处理的的文件为非压缩格式或者压缩可切分,且inputFormat为CombineHiveInputFormat时,
则控制map个数是由以下四个参数起作用,关于这四个参数作用优先级与使用注意事项请参考如下:
一般来讲这几个参数的结果大小要满足以下条件:
max.split.size >= min.split.size >= min.size.per.node >= min.size.per.rack
几个参数的作用优先级为:
max.split.size <= min.split.size <= min.size.per.node <= min.size.per.rack
总结:所以对于控制map的个数进行调优,首先需要看是否开启了压缩,压缩算法是否支持切分,参数的设置等等!
5、**set mapred.min.split.size.per.node=256000000;**
一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并) ,
和第3和第4个参数一起配合使用。
6、**set mapred.min.split.size.per.rack=256000000;**
一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并) ,
也适合第3,4,5的参数一起配合使用。
7、**set hive.exec.mode.local.auto=true;**
开启本地模式,这个参数在自己学习中可能经常用到,但是在实际生产中用到的还是比较少,
因为这个参数开启后,针对的是小数据集,在单台机器上处理所有的任务,对生产中的任务不适用!
8、**set hive.exec.recers.bytes.per.recer=512*1000*1000;**
每个rece任务处理的数据量,默认为256M,在hive0.14.0之前默认是1G,我们公司设置的是512M,写的是512*1000*1000因为在网络传输中用的是1000,而不是1024机制,
将该参数值调小可以增加rece的数量,提高运行的效率,
当然也不是rece的数量越多越好,因为启动和初始化rece都是会消耗资源和时间的,
而且有多少个rece就会有多少个输出文件,如果这些文件作为下一个任务的输入,就会造成小文件过多的问题
9、**hive.exec.recers.max**
每个任务最大的rece数,默认为1009,在hive0.14.0之前默认是999
计算recer数的公式很简单N=min(参数9,总输入数据量/参数8)
即,如果rece的输入(map的输出)总大小不超过1G,那么只会有一个rece任务;
10、**set mapred.rece.tasks = 15;**
设置rece的个数(在实际生产中谨慎使用)
那么什么时候可以进行手动设定rece数量呢?比如系统自动计算的rece个数,因为集群资源不足,
造成程序运行出现OOM(内存溢出不足)时,可以根据推定的rece个数手动增加数量,保证程序在跑的慢的基础上可以完整运行
那么在什么情况下只有一个rece呢?
<1>、当map的输出文件小于hive.exec.recers.bytes.per.recer时
<2>、手动设置set mapred.rece.tasks =1时
<3>、使用了order by时(全局排序会使用一个rece去处理)
<4>、表关联时出现笛卡尔积
<5>、单独使用count时,比如:select count(*) from tablename,
如果改写加入了group by配合使用就不会出现一个rece,比如:select sign_date,count(*) from tablename group by sign_date;
11、**set mapred.job.reuse.jvm.num.tasks=10;**
用于避免小文件的场景或者task特别多的场景,这类场景大多数执行时间都很短,因为hive调起maprece任务,JVM的启动过程会造成很大的开销,尤其是job有成千上万个task任务时,JVM重用可以使得JVM实例在同一个job中重新使用N次
12、**set hive.exec.dynamic.partition=true;**
表示开启动态分区功能
13、**set hive.exec.dynamic.partition.mode=nonstrict;**
表示允许所有分区都是动态的,
默认是strict,表示必须保证至少有一个分区是静态的
14、**set hive.groupby.skewindata=true;**
有数据倾斜的时候进行负载均衡 ,决定group by操作是否支持倾斜数据,其实说白了就相当于MR中的conbiner做了一次预聚合。
注意:只能对单个字段聚合。
控制生成两个MR Job,第一个MR Job Map的输出结果随机分配到rece中减少某些key值条数过多某些key条数过小造成的数据倾斜问题。
在第一个 MapRece 中,map 的输出结果集合会随机分布到 rece 中, 每个rece 做部分聚合操作,并输出结果。这样处理的结果是,相同的 Group By Key 有可能分发到不同的rece中,从而达到负载均衡的目的;
第二个 MapRece 任务再根据预处理的数据结果按照 Group By Key 分布到 rece 中(这个过程可以保证相同的 Group By Key 分布到同一个 rece 中),最后完成最终的聚合操作
15、**set hive.auto.convert.join=true;**
开启map join
16、**set hive.mapjoin.smalltable.filesize=512000000;**
map join的小表的大小,也是开启和关闭map join的阈值
17、**hive.exec.compress.output=true;**
开启压缩,我们公司使用的是默认的压缩算法deflate
压缩算法有:<1>、org.apache.hadoop.io.compress.GzipCodec,
<2>、org.apache.hadoop.io.compress.DefaultCodec,
<3>、com.hadoop.compression.lzo.LzoCodec,
<4>、com.hadoop.compression.lzo.LzopCodec,
<5>、org.apache.hadoop.io.compress.BZip2Codec
使用的压缩算法:
set maprece.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.DefaultCodec
**针对上述小文件合并的三个参数值做以下解释:**
大于文件块大小128m的,按照128m来分隔,小于128m,大于100m的,按照100m来分隔,把那些小于100m的(包括小文件和分隔大文件剩下的),进行合并
‘捌’ Hive执行简单查询,耗时巨长,是什么情况
秆第九源诎裸露咎