HIVE优化理论篇

引言:

HIVE优化其实分为四块去说比较好。1.架构,2.sql上优化,3.对mapreduce的优化,因为hive是将sql转换成mapreduce去执行,这其实也包含了对架构或者参数上进行一些优化,4.针对数据倾斜如何处理,5.表优化

1. 架构上优化

1.1 严格模式:

 严格模式的意思就是:如果sql产生笛卡尔积,或者没有查询分区没带分区列,或者order by没用limit那么这段sql就会执行报错。

1.2 并行执行

并行执行的意思就是:没有相互依赖的mr任务,可以同时执行,比如说多个union all 这种。

1.3 推测执行

推测执行的意思就是:用空间来换时间,比如由于网络,资源不均等原因,某些任务运行特别慢,会启动备份进程处理同一份数据,并最终选用最先成功的计算结果作为最终结果。

1.4 本地模式

本地模式的意思就是:如果你得数据量比较小,这种就没必要通过集群即启动分布式来跑这份数据,就在本地执行,节约资源也相对比较快,不需要集群启动所消耗掉的时间。

1.5 jvm重用

jvm重用的意思就是:在mr里面,是以进程为单位的,一个进程就是一个Jvm,其实像短作业,这些进程能够重用就会很快,但是它的缺点是会等任务执行完毕后task插槽,这个在数据倾斜时候较为明显。

1.6 其他

当然还有很多其他的一些配置上的优化,不一一介绍。

2.SQL上的优化

2.1 把多次使用的中间结果存在临时表

这个意思就是:比如说我的来源表 有a,b,c三个表,但是我b表需要多次使用即a left join b left join b left join b left join c ,那么这里可以将b表数据存入临时表,这样做的目的,减少IO,降低MR大量进行读写磁盘的操作。

2.2 谓词下推

这个就是将过滤条件放入里面。比如 (SELECT * FROM A)LEFT JOIN (SELECT * FROM B) ON A.id=B.id WHERE B.areacode IS NOT NULL 这里替换成SELECT * FROM A)LEFT JOIN (SELECT * FROM B WHERE areacode IS NOT NULL) ON A.id=B.id 

2.3 sort by,distribute by 代替order by

order by是会对某个字段进行全局排序,将map端的数据全部放在一个reduce里面去进行操作,如果这个map端数据量大,很容易跑不出来。然后sort by 其实会启动多个reduce来进行排序,而且reduce数据是有序的,而distribute by的目的就是均匀分配map到reduce端的数据,,不加的话就会随机进行分配。

2.4 count(distinct )用group by +count 来实现

为什么很多人都在说少用count(distinct ),因为这个会让数据进入一个reduce进行处理,数据量较大就会,这个job就会很慢。

2.5 注意关联字段的null或者笛卡尔积

关联字段为null的太多会造成数据倾斜,所以需要提前去掉,因为一般为null值在开发中意义也不大,也要注意关联字段发生笛卡尔积可能性。

2.6 注意大小表join

将小表放在join操作符左边,因为在进行redure阶段,左边表数据放入内存,这样就会减少oom情况的发生,虽然hive比较高级的版本对这个已经进行优化,但是一般生产环境hive版本不会这么高。

3.争对mapreduce优化

因为hivesql是转换成mapreduce进行数据操作,所以争对mapreduce的优化:

3.1 数据输入

在数据源端就可以将多个小文件进行合并。

3.2 MAP端

进行spil操作就是溢写,调大环形缓冲区的大小,以及调大溢写的阈值,默认0.8溢写,减少spill操作,减少网络io
如果切片太多即map的spilt操作,这样一个切片对应一个maptask任务,启动过多的maptask的时间可能就会比map端处		  理数据时间消耗的更多,白白浪费资源。可以通过。max.spilt.size和min.spilt.size来控制切片大小,如果这两个参数设置的太小就会产生多个maptask,所以需要进行调大该参数,如果你设置参数很大,你得数据又比较复杂,一个maptask去处理大量数据,那么也消耗资源和时间,所以比如你得该文件大小127M,那么你可以让他切成多块 进行计算。

3.3REDUCE端

有多少个reduce,就会有个多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题,hive的reducetask会自己计算,参数是mapred.reduce.tasks=-1就hive自己计算,如果不合理你也可以进行通过其他参数调节来进行控制reducetask数量,注意需要合理过多会导致任务变慢,过少task去处理可能会发生oom。
reduce的buffer:默认情况下,数据达到阈值,buffer数据就会写入磁盘,而reduce又去磁盘拉取数据,这样网络io比较大。那么我们可以考虑将数据从buffer直接输送到reduce端,这样减少一些io开销,这个参数mapred.job.reduce.input.buffer.percent。

3.4 压缩

可以将数据进行压缩,减少网络io开销和时间。

4.数据倾斜

4.1 解读

数据倾斜是发生shuffle是产生的,因为shuffle是通过key,values对形式拉取,聚合数据的。如果是你得key比较集中,即key比较少而value比较多 ,而相同key会被拉到一个或者少量节点进行聚合计算,那么就会少量节点或者单点节点处理过多的数据。

4.2 产生倾斜的原因

key值分布不均匀,存在大量空值,存在大量相同的值。
业务数据本身特性就会产生数据倾斜,比如说电信MR数据,MR即人跟基站交互一次就算一次MR,如果在省份下去进行聚合就会很容易数据倾斜
sql本身产生:比如你写出笛卡尔积;或者你得group by维度较高比如说就group by 中国,那么你可以通过分段聚合先聚合到省份,再把这份数据聚合到全国;count(distinct) 用sum group by代替。

4.3 解决方案

4.3.1 争对聚合产生数据倾斜

开启map端聚合:hive.map.aggr=true 条数也能控制 hive.grouby.mapaggr.checkinterval=1000000
负载均衡:hive.groupby.skewindata = true,这个参数的意思就是会开启一个预聚合在聚合的作用,详细一点,在第一个 MapReduce 中,map 的输出结果集合会随机分布到 reduce 中, 每个 reduce 做部分聚合操作,并输出结果。相同的 Group By Key 有可 能分发到不同的 reduce 中,从而达到负载均衡的目的;第二个 MapReduce 任务再根据预处 理的数据结果按照 Group By Key 分布到 reduce 中(这个过程可以保证相同的 Group By Key 分布到同一个 reduce 中),最后完成最终的聚合操作

4.3.2 关联字段null值或者异常值造成数据倾斜

 解决方案:第一个直接进行过滤;第二个先查出不为null的数据进行关联 union all 查出null的字段 第三个 给null或者异常值加随机数 一般来说就是这三个方法。

4.3.3 key值分布集中

核心思路:将key值打散,因为shuffle会将相同key拉取到一个或者少量节点进行进行,那将key打散比如增加随机数,举个例子之前key为1的有一百条,加100个随机数1_1,1_2。。。。。1_100那么这个key就被打散成一百个,就不会在一个reduce进行处理。
当然用mapreduc的也有一些优化,加jvm的大小,这个适合于key值比较少情况;增加reducetask的数量,这个适合于key多,但是数据大量集中在少量key上。

4.3.4 大表join大表

熟悉业务可以将大表拆分,如果不能拆分抽取key单独出来进行union all,再加上临时表的形式

5.表优化

在创建表的时候可以进行压缩,列式存储等形式进行优化
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值