hive 核心思想:
把 Hive SQL 当做 Mapreduce 程序去优化。
以下 SQL 不会转为 Mapreduce 来执行:
select 仅查询本表字段; where 仅对本表字段做条件过滤。
explain 命令可以显示执行计划:
EXPLAIN [EXTENDED] query; EXTENDED 可以看到更详细 的信息。
本地模式提高执行效率
本地模式:
mapreduce 任务运行在一台节点上,该节点把需要的资源从其他机器 copy 过来
集群模式:
mapreduce 任务在 hadoop 集群中执行 开启本地模式:
set hive.exec.mode.local.auto=true;
注意:
hive.exec.mode.local.auto.inputbytes.max 默认值为 128M,表示加载文件的最大值,若 大于该配置仍会以集群方式来运行
查询的数据在数据量不大的表中,这种情况使用本地模式,数据量大时使用集群模式
并行计算
hive 执行 sql 默认是顺序执行,如下 sql 如果使用并行计算会大大提高效率,但是集群 压力也增大:
select wc.col1,bk.col2 from
(select count(*) as col1 from wordcount) wc,
(select count(*) as col2 from bucket) bk;
两条子查询可以使用并行计算
通过设置以下参数开启并行模式:
set hive.exec.parallel=true;
注意:
hive.exec.parallel.thread.number
代表一次 SQL 计算中允许并行执行的 job 个数的最大值
严格模式
查询限制:
1) 对于分区表,必须添加 where 对于分区字段的条件过滤;
2) order by 语句必须包含 limit 输出限制;
3) 限制执行笛卡尔积的查询。
笛卡尔集中的记录不一定正确,为了避免笛卡尔集可以在 WHERE 中加入有效的连接条 件,实际运行环境下应该避免使用笛卡尔全集。
通过设置以下参数开启严格模式:
set hive.mapred.mode=strict;(默认为:nonstrict 非严格模式)
Hive 排序
Order By 对于查询结果做全排序,只允许有一个 reduce 处理。当数据量较大时,应慎用。严格 模式下,必须结合 limit 来使用
Sort By 对于单个 reduce 的数据进行排序
Distribute By 分区排序,经常和 Sort By 结合使用
Cluster By 相当于 Sort By + Distribute By,
Cluster By 不能通过 asc、desc 的方式指定排序规则; 可通过 distribute by column sort by column asc|desc 的方式结合使用。
Hive join
Join 计算时,将小表(驱动表)放在 join 的左边
Map Join:在 Map 端完成 Join(避免数据倾斜)
两种实现方式:
1) SQL 方式,在 SQL 语句中添加 MapJoin 标记(mapjoin hint)
语法:
SELECT /*+ MAPJOIN(smallTable) */ smallTable.key, bigTable.value FROM smallTable JOIN bigTable ON smallTable.key = bigTable.key;
2) 开启自动的 MapJoin
通过修改以下配置启用自动的 mapjoin:
set hive.auto.convert.join = true; 该参数为 true 时,Hive 自动对左边的表统计量,如果是小表就加入内存,即对小表使 用 Map join
相关配置参数:
hive.mapjoin.smalltable.filesize;
大表小表判断的阈值,如果表的大小小于该值则会被加载到内存中运行
hive.ignore.mapjoin.hint; 默认值:true;
是否忽略 mapjoin hint 即 mapjoin 标记
hive.auto.convert.join.noconditionaltask; 默认值:true;
将普通的 join 转化为普通的 mapjoin 时,是否将多个 mapjoin 转化为一 个 mapjoin
hive.auto.convert.join.noconditionaltask.size;
最多可以把几个 mapjoin 转化为一个 mapjoin
Map-Side 聚合
通过设置以下参数开启在 Map 端的聚合:
set hive.map.aggr=true;
相关配置参数:
hive.groupby.mapaggr.checkinterval:
map 端 group by 执行聚合时处理的多少行数据(默认:100000)
hive.map.aggr.hash.min.reduction:
进行聚合的最小比例,预先对 100000 条数据做聚合,若聚合之后的数据量/100000 的 值大于该配置 0.5,则不会聚合 hive.map.aggr.hash.percentmemory:
map 端聚合使用的内存的最大值
hive.map.aggr.hash.force.flush.memory.threshold:
map 端做聚合操作时 hash 表的最大可用内存,大于该值则会触发 flush,溢写到磁盘
hive.groupby.skewindata
是否对 GroupBy 产生的数据倾斜做优化,默认为 false
控制 Hive 中 Map 以及 Reduce 的数量
Map 数量相关的参数:
mapred.max.split.size
一个 split 的最大值,即每个 map 处理文件的最大值
mapred.min.split.size.per.node
一个节点上 split 的最小值
mapred.min.split.size.per.rack
一个机架上 split 的最小值
Reduce 数量相关的参数:
mapred.reduce.tasks
强制指定 reduce 任务的数量
hive.exec.reducers.bytes.per.reducer
每个 reduce 任务处理的数据量
hive.exec.reducers.max
每个任务最大的 reduce 数
JVM 重用
适用场景:
1) 小文件个数过多
2) task 个数过多 频繁的申请资源,释放资源降低了执行效率
通过 set mapred.job.reuse.jvm.num.tasks=n; (n 为 task 插槽个数)来设置,道理与 “池”类似。
缺点:
设置开启之后,task 插槽会一直占用资源,不论是否有 task 运行,直到所有的 task 即 整个 job 全部执行完成时,才会释放所有的 task 插槽资源。