共计 4337 个字符,预计需要花费 11 分钟才能阅读完成。
Hive 作为大数据畛域罕用的数据仓库组件,在设计和开发阶段须要留神效率。影响 Hive 效率的不仅仅是数据量过大;数据歪斜、数据冗余、job 或 I / O 过多、MapReduce 调配不合理等因素都对 Hive 的效率有影响。对 Hive 的调优既蕴含对 HiveQL 语句自身的优化,也蕴含 Hive 配置项和 MR 方面的调
整。
从以下三个方面开展:
架构优化
参数优化
SQL 优化
1. 架构方面
执行引擎方面针对公司内平台的资源,抉择更适合的更快的引擎,比方 MR、TEZ、Spark 等,
如果抉择是 TEZ 引擎,能够在优化器时候开启向量化的优化器,另外能够抉择老本优化器 CBO,配置别离如下:
set hive.vectorized.execution.enabled = true; - | |
- 默认 false | |
set hive.vectorized.execution.reduce.enabled = true; - | |
- 默认 false | |
SET hive.cbo.enable=true; -- 从 v0.14.0 默认 | |
true | |
SET hive.compute.query.using.stats=true; -- 默认 false | |
SET hive.stats.fetch.column.stats=true; -- 默认 false | |
SET hive.stats.fetch.partition.stats=true; -- 默认 true |
在表的设计上优化,比方抉择分区表,分桶表,以及表的存储格局,为了缩小数据传输,能够应用压缩的形式,上面给几个参数(更多参数能够查看官网)
-- 两头后果压缩 | |
SET | |
hive.intermediate.compression.codec=org.apache.hadoop.io.compress.SnappyCodec ; | |
-- 输入后果压缩 | |
SET hive.exec.compress.output=true; | |
SET mapreduce.output.fileoutputformat.compress.codec =org.apache.hadoop.io.compress.SnappyCodc |
2. 参数优化
第二局部是参数优化,其实下面架构局部,有局部也是通过参数来管制的,这一部分的参数管制次要有上面几个方面
本地模式、严格模式、JVM 重用、并行执行、揣测执行、合并小文件、Fetch 模式
2.1 本地模式
当数据量较小的时候,启动分布式解决数据会比较慢,启动工夫较长,不如本地模式快,用上面的参数来调整
SET hive.exec.mode.local.auto=true; -- 默认 false | |
小 | |
SET hive.exec.mode.local.auto.inputbytes.max=50000000; -- 输出文件的大小小于 hive.exec.mode.local.auto.inputbytes.max 配置的大 | |
SET hive.exec.mode.local.auto.input.files.max=5; -- 默认 4 map 工作的数量小于 hive.exec.mode.local.auto.input.files.max 配置的 | |
大小 |
2.2 严格模式
这其实是个开关,满足上面三个语句时候,就会失败,如果不开启就失常执行,开启后就让这些语句主动失败
hive.mapred.mode=nostrict | |
-- 查问分区表时不限定分区列的语句;-- 两表 join 产生了笛卡尔积的语句;-- 用 order by 来排序,但没有指定 limit 的语句 |
2.3 Jvm 重用
在 mr 外面,是以过程为单位的,一个过程就是一个 Jvm, 其实像短作业,这些过程可能重用就会很快,然而它的毛病是会等工作执行结束后 task 插槽,这个在数据歪斜时候较为显著。开启这个应用上面的参数
SET mapreduce.job.jvm.numtasks=5;
2.4 并行执行
Hive 的查问会转为 stage,这些 stage 并不是相互依赖的,能够并行执行这些 stage,应用上面的参数
SET hive.exec.parallel=true; -- 默认 false | |
SET hive.exec.parallel.thread.number=16; -- 默认 8 |
2.5 揣测执行
这个参数的作用是,应用空间资源来换取失去最终后果的工夫,比方因为网络,资源不均等起因,某些工作运行特地慢,会启动备份过程解决同一份数据,并最终选用最先胜利的计算结果作为最终后果。
set mapreduce.map.speculative=true | |
set mapreduce.reduce.speculative=true | |
set hive.mapred.reduce.tasks.speculative.execution=true |
2.6 合并小文件
在 map 执行后面,先合并小文件来缩小 map 数
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
在工作完结后,合并小文件
# 在 map-only 工作完结时合并小文件,默认 true | |
SET hive.merge.mapfiles = true; | |
# 在 map-reduce 工作完结时合并小文件,默认 false | |
SET hive.merge.mapredfiles = true; | |
# 合并文件的大小,默认 256M | |
SET hive.merge.size.per.task = 268435456; | |
# 当输入文件的均匀大小小于该值时,启动一个独立的 map-reduce 工作进行文件 merge | |
SET hive.merge.smallfiles.avgsize = 16777216; |
2.7 Fetch 模式
最初一种 fetch 模式,则是在某些状况下尽量不跑 mr,比方查问几个字段,全局查找,字段查,limit 查等状况
hive.fetch.task.conversion=more
3.sql 优化
这一部分较简单,可能波及到数据歪斜问题,至于数据歪斜问题始终是大数据处理的不可比防止的一个问题,解决形式也较多
3.1 sql 优化
sql 优化是开发人员最容易管制的局部,往往是教训使之,大概总结一下又上面的形式
列,分区拆解,sort by 代替 order by, group by 代替 count(distinct),group by 的预聚合(通过参数来管制),歪斜配置项,map join,独自过滤空值,适当调整 map 和 reduces 数,这些在工作中简直都会碰到,尽可能去优化他们呢是你要做的
3.2 歪斜平衡配置项
这个配置与 group by 的歪斜平衡配置项殊途同归,通过 hive.optimize.skewjoin 来配置,默认 false。如果开启了,在 join 过程中 Hive 会将计数超过阈值 hive.skewjoin.key(默认 100000)的歪斜 key 对应的行长期写进文件中,而后再启动另一个 job 做 map join 生成后果。通过 hive.skewjoin.mapjoin.map.tasks 参数还能够管制第二个 job 的 mapper 数量,默认 1000
3.3 独自解决歪斜 key
如果歪斜的 key 有理论的意义,一般来讲歪斜的 key 都很少,此时能够将它们独自抽取进去,对应的行独自存入长期表中,而后打上一个较小的随机数前缀(比方 0~9),最初再进行聚合。不要一个 Select 语句中,写太多的 Join。肯定要理解业务,理解数据。(A0-A9)分成多条语句,分步执行;(A0-A4; A5-A9);先执行大表与小表的关联;
4. 两个 SQL
4.1 找出全副夺得 3 连贯的队伍
team,year
活塞,1990
公牛,1991
公牛,1992
-- | |
-- 1 排名 | |
select team, year, | |
row_number() over (partition by team order by year) as rank | |
from t1; | |
-- 2 获取分组 id | |
select team, year, | |
row_number() over (partition by team order by year) as rank, | |
(year -row_number() over (partition by team order by year)) as groupid | |
from t1; | |
-- 3 分组求解 | |
select team, count(1) years | |
from (select team, | |
(year -row_number() over (partition by team order by year)) as groupid | |
from t1 | |
) tmp | |
group by team, groupid | |
having count(1) >= 3; |
4.2 找出每个 id 在在一天之内所有的波峰与波谷值
波峰:
这一时刻的值 > 前一时刻的值
这一时刻的值 > 后一时刻的值
波谷:
这一时刻的值 < 前一时刻的值
这一时刻的值 < 后一时刻的值
id time price 前一时刻的值(lag)后一时刻的值(lead)
sh66688, 9:35, 29.48 null 28.72
sh66688, 9:40, 28.72 29.48 27.74
sh66688, 9:45, 27.74
sh66688, 9:50, 26.75
sh66688, 9:55, 27.13
sh66688, 10:00, 26.30
sh66688, 10:05, 27.09
sh66688, 10:10, 26.46
sh66688, 10:15, 26.11
sh66688, 10:20, 26.88
sh66688, 10:25, 27.49
sh66688, 10:30, 26.70
sh66688, 10:35, 27.57
sh66688, 10:40, 28.26
sh66688, 10:45, 28.03
-- 思路:要害是找到波峰波谷的特色 | |
-- 波峰的特色: 大于前一个时间段、后一个时间段的值 | |
-- 波谷的特色: 小于前一个时间段、后一个时间段的值 | |
-- 找到这个特色 SQL 就好写了 | |
select id, time, price, | |
case when price > beforeprice and price > afterprice then "波峰" | |
when price < beforeprice and price < afterprice then "波谷" end as feature | |
from (select id, time, price, | |
lag(price) over (partition by id order by time) beforeprice, | |
lead(price) over (partition by id order by time) afterprice | |
from t2 | |
)tmp | |
where (price > beforeprice and price > afterprice) or | |
(price < beforeprice and price < afterprice); |
吴邪,小三爷,混迹于后盾,大数据,人工智能畛域的小菜鸟。
更多请关注