大数据(二十三):hive优化、表优化

一、Fetch抓取

        Fetch抓取是指,Hive中对某些情况的查询可以不必使用MapReduce计算。例如,select * from employees;在这种情况下,Hive可以简单读取employee对应的存储目录下的文件,然后输出查询结果到控制台。

        在hive-default.xml.template文件中hive.fetch.task.conversion默认是more,老版本hive默认是minimal,该属性修改为move以后,在全局查询、字段查找、limti查询查找等都不是MapReduce。

<property>
    <name>hive.fetch.task.conversion</name>
    <value>more</value>
</property>

二、本地模式

        大多数的HadoopJob是需要Hadoop提供的完整的可扩展性来处理大数据集,不过有时Hive的输入量非常小的。这种情况下,为查询触发执行任务消耗的时间可能会比实际job的执行时间要多得多。对于大多数这种情况,hive可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显被缩短。

        用户可以通过设置hive.exec.mode.local.auto的值为true,来让Hive在适当的时候自动启动这个优化。

开启本地mr

set hive.exec.mode.local.auto=true;

设置local.mr的最大输入数据量,当输入数据量小于这个值时采用local.rm的方式,默认为134217728,即128M

set hive.exec.mode.local.auto.inputbytes.max=500000000;

设置local.mr的最大输入文件个数,当输入文件个数小于这个值时采用local.mr方式,默认为4

set hive.exec.mode.local.auto.input.files.max=10;

三、小表、大表Join

        将key相对分散,且数据量小的表放在join的左边,这样可以有效减少内存溢出错误发生的几率;再进一步,可以使用Group让小的维度表(1000条以下的记录条数)先进内存。在map端完成Reduce。

        实际上新版的hive已经对小表JOIN大表和大表JOIN小表进行了优化,已经没什么区别。

可以通过参数关闭掉这个优化

set hive.auto.convert.join = false;

四、大表JOIN大表

1.空Key过滤

        有时join超时是因为某些key对应的数据太多,而相同key对应的数据都会发送到相同的reducer上,从而导致内存不够。此时我们应该仔细分析这些异常的key,很多情况下,这些key对应的数据是异常数据,我们需要在SQL语句中进行过滤,过滤掉key对应的字段为空。

        1.配置历史服务器

        配置mapred-site.xml

<property>
    <name>mapreduce.jobhistory.address</name>
    <value>{服务器地址}:10020</value>
</property>
<property>
    <name>mapreduce.jobhistory.webapp.address</name>
</property>

        2.关闭MapJoin功能

set hive.auto.convert.join = flase;

        3.执行不过滤空id的语句

insert overwrite table jointable
selet n.* from nullidtable n left ori o on n.id = o.id;

        4.执行过滤空id的语句

insert overwrite table jointable
select n.* from(select * from nullidtable where id is not null)n left join ori on n.id = o.id

2.空key转换

        有时虽然某个key为空对应的数据很多,但是相应的数据不是异常数据,必须要包含在join的结果中,此时我们可以表a中key为空的字段赋值一个随机的值, 使得数据随机均匀放分不痛的reducer上。

        1.设置5个reduce个数

set mapreduce.job.reduces = 5;

        2.两种表join

insert overwrite table jointable
select n.* from nullidtable n full join ori o on
case when n.id is null then concat("hive",rand()) else n.id end = o.id;

五、MapJoin

        如果不指定MapJoin或者不符合MapJoin的条件,那么Hive解析器会将Join操作转换成Common Join,即在Reduce阶段完成Join。容易发生数据倾斜。可以用MapJoin把小表全部加载到内存map端进行Join,避免reducer处理。

1.开启MapJoin参数设置

        1.设置自动选择MapJoin(默认为true)

set hive.auto.convert.join = true;

        2.大表小表的值域设置(默认25M以下认为是小表)

set hive.mapjoin.smalltable.filesize=25000000

六、Group By

        默认情况下,Map阶段同一key数据分发给一个reduce,当一个key数据过大时就倾斜了。并不是所有的聚合操作都需要在Reduce端完成,很多聚合操作可以先在map端进行部分聚合,最后在Reduce端得出最终结果。

1.是否在Map端进行聚合(默认为True)

set hive.map.aggr = true

2.在Map端进行聚合操作的条目数目

set hive.groupby.mapaggr.checkinterval = 100000

3.数据倾斜的时候进行负载均衡(默认是false)

set hive.groupby.skewindata = true

        当选项设定为true,生成的查询计划会有两个MRjob。第一个job中,Map的输出结果会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果。这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个Job在根据预处理的数据结果按照Group By Key分不到Reduce中,最后完成最终的聚合操作。


 

猜你喜欢

转载自blog.csdn.net/qq_34886352/article/details/82969469