-
Hive 优化
- 核心思想:把 Hive SQL 当做 Mapreduce 程序去优化
- 以下 SQL 不会转为 Mapreduce 来执行
- select 仅查询本表字段
- where 仅对本表字段做条件过滤
-
Explain 显示执行计划
- explain extended SQL语句
-
Hive 抓取策略
- Hive 中对某些情况的查询不需要使用 MapReduce 计算
-
抓取策略
- Set hive.fetch.task.conversion=none/more;
-
Hive 运行方式
- 本地模式
- 集群模式
-
本地模式
- 开启本地模式
- set hive.exec.mode.local.auto=true; (方便测试、快)
- 注意
- hive.exec.mode.local.auto.inputbytes.max 默认值为 128 MB
- 表示加载文件的最大值,若大于该配置仍会以集群方式来运行
- 开启本地模式
-
并行计算
- 通过设置以下参数开启并行模式
- set hive.exec.parallel=true;
- 注意
- hive.exec.parallel.thread.number (默认值为 8)
- 一次 SQL 计算中允许并行执行的 job 个数的最大值
- 通过设置以下参数开启并行模式
-
严格模式
- 通过设置以下参数开启严格模式
- set hive.mapred.mode=strict;
- 默认为:nonstrict 非严格模式
- set hive.mapred.mode=strict;
- 查询限制
- 1、对于分区表,必须添加 where 对于分区字段的条件过滤
- 2、order by 语句必须包含 limit 输出限制
- 3、限制执行笛卡尔积的查询
- 通过设置以下参数开启严格模式
-
Hive 排序
- Order By :对于查询结果做全排序,只允许有一个 reduce 处理
- 当数据量较大时,应慎用
- 严格模式下,必须结合 limit 来使用
- 一般不用
- Sort By :对于单个 reduce 的数据进行排序
- ReduceTask 可自定数量
- Reduce 内的数据排序
- 但每个 Reduce 之间的排序就不一定
- 相当于内部排序
- Distribute By:分区排序,经常和 Sort By 结合使用
- 对每个 Reduce 之间进行排序
- 相当于外部排序
- 一般 Distribute By + Sort By 结合使用
- distribute by 字段 sort by 字段 asc|desc 的方式
- Cluster By:相当于 Sort By + Distribute By
- Cluster By 不能通过 asc、desc 的方式指定排序规则
- 一般不用,默认是升序时可用
- Order By :对于查询结果做全排序,只允许有一个 reduce 处理
-
Hive Join 小表:大表
- 尽量使用相同的连接键(会转化为一个 MapReduce 作业处理)
- Map Join :在 Map 端完成 Join
- 两种实现方式
- 手动
- SQL 方式,在 SQL 语句中添加 MapJoin 标记 (mapjoin hint)
- 小表左边,大表右边,手动没有要求,但尽量规范
- 语法
- select /*+MAPJOIN( 小表 )*/ 小表.key,大表.value from 小表Join 大表ON 小表.key = 大表.key;
- 语法
- 自动
- 开启自动的 MapJoin
- 小表左边,大表右边的强要求
- 相关配置参数
- set hive.auto.convert.join = true;
- 参数为 true 时,Hive 自动对左边的表统计量,如果是小表就加入内存,即对小表使用 Map join
- hive.mapjoin.smalltable.filesize
- 默认 25M,单位字节
- 大表小表判断 的阈值,如果表的大小 < 该值则会被加载到内存中运行
- hive.ignore.mapjoin.hint
- 默认为 true,是否忽略 mapjoin hint 即 mapjoin 标记
- 为 true 时,按自动处理
- set hive.auto.convert.join = true;
- 手动
-
Hive Join 大表:大表
- 尽量使用相同的连接键(会转化为一个 MapReduce 作业处理)
- 大表 join 大表的优化并没有太多的提升,也只是相对优化一点
- 空 Key 过滤
- 有时 join 超时是因为某些 Key 对应的数据太多,而相同 Key 对应的数据都会发送到相同的 Reducer 上,从而导致内存不够。
- 分析异常 Key ,很多情况下,这些 Key 对应的数据是异常数据,需要在 SQL 语句中进行过滤
- 空 Key 转换
- 有时某些 Key 为空对应的数据很多,但相应的数据并不是异常数据,必须要包含在 join 的结果中
- 此时可以在表 a 中 Key 为空的字段赋一个随机值,使得数据随机均匀到不同 Reduce上
-
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.groupby.skewindata
- 是否对 group by 产生的数据倾斜做优化,默认:false
- 解决倾斜问题,但处理时长增加,最终是否处理结束不一定,因为优化也只是相对的
- hive.groupby.mapaggr.checkinterval
- 开启 Map 端的聚合
-
合并小文件
- 文件数目小,容易在文件存储端造成压力,给 hdfs 造成压力,影响效率、IO 问题
- 越大越好,但不能超过块 block 大小
- 设置合并属性
- 是否合并 map 输出文件:hive.merge.mapfiles=true
- 是否合并 reduce 输出文件:hive.merge.mapredfiles=true
- 合并文件的大小:hive.merge.size.per.task=256*1000*1000
- 文件数目小,容易在文件存储端造成压力,给 hdfs 造成压力,影响效率、IO 问题
-
去重统计
- 数据量小的时候无所谓
- 数据量大的情况
- 由于 count distinct 操作需要用一个 Reduce Task 来完成
- 这个 Reduce 需要处理的数据量太大,就会导致整个 Job 很难完成
- 一般 count distinct 使用先 group by 再 count 的方式替换
-
控制 Hive 中 Map 与 Reduce 的数量
- Map 数量相关参数
- mapred.max.split.size
- 一个 split 的最大值,即每个 map 处理文件的最大值
- mapred.min.split.size.per.node
- 一个节点上 split 的最小值
- mapred.min.split.size.per.rack
- 一个机架上 split 的最小值
- mapred.max.split.size
- Reduce 数量相关参数
- mapred.reduce.tasks
- 强制指定 reduce 任务的数量
- hive.exec.reducers.bytes.per.reducer
- 每个 reduce 任务处理的数据量
- hive.exec.reducers.max
- 每个任务最大的 reduce 数
- mapred.reduce.tasks
- Map 数量相关参数
-
Hive - JVM 重用
- 适用场景
- 小文件个数过多
- task 个数过多
- 通过 set mapred.job.reuse.jvm.num.tasks=n;
- n:task 插槽数量
- 缺点
- 设置开启后,task 插槽会一直占用资源,不论是否有 task 运行,直到所有的 task 即整个 job 全部执行完成时,才会释放所有的 task 插槽资源
- 适用场景
Hive:调优
于 2021-08-24 13:57:05 首次发布