每日分享 Hive
一、Hive是什么?
Hive提供了一种SQL(结构化查询)语言,可以将结构化的文件映射为一张表,查询存储在HDFS上的数据或者其他在HDFS上的文件系统,例如HBase。
优点:
- 操作接口采用类SQL的语法,快速开发
- 避免学习MapReduce,减小学习成本
- 支持用户自定义函数
- 处理大数据便捷
缺点:
- 执行延迟比较高,自动生成的MapReduce作业比较慢
- 表达能力有限,体现在迭代式算法无法表达、MapReduce数据处理流程限制,无限实现效率更高的算法
- 不支持记录级别的更新、插入、删除操作
二、Hive架构
用户接口(Client):CLI、JDBC/ODBC、WEBUI
元数据(Meta store):表名、表所属数据库、表的拥有者、列/分区字段、表的类型(内、外部表)、表的数据所在目录等
驱动器(Driver)
- 解析器:将SQL字符串转换成抽象语法树AST,一般都用第三方工具完成,比如antlr
- 编译器:将AST编译成逻辑执行计划
- 优化器:将逻辑执行计划进行优化
- 执行器:将逻辑执行计划转化为物理计划,例如MR/SPARK
三、Hive内外部表
内部表、外部表:是否被external修饰
内部表存储的位置:hive.metastore.warehouse.dir(默认是 /user/hive/warehouse)
外部表数据存储位置是自己规定的(如果没有location)在HDFS上的/user/hive/warehouse下以外部表的表名创建一个文件夹
内部表的数据由Hive自身管理
外部表的数据有HDFS管理
创建表:
创建内部表时,数据将移动到数据仓库指向的路径
创建外部表时,仅记录数据所在路径
删除表:
删除内部表时,元数据和数据一起被删除
删除外部表时,只删除元数据
外部表的优点:
- 外部表不会加载到Hive的默认仓库,减少数据的传输,同时还能和其他外部表共享数据
- 使用外部表,hive不会修改源数据,不用担心数据损坏或丢失
四、Hive数据倾斜
什么是数据倾斜?
数据倾斜主要表现在 map/reduce 程序执行时,reduce节点大部分执行完毕,但有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长。
这是因为某一个key的条数比其他key多很多,这条key节点所处理的数据量比其他节点大很多,从而导致某几个节点迟迟运行不完。
数据倾斜的原因
join:其中一个表较小、但key集中,分发到某一个或者几个reduce上的数据远远高于平均值
大表与大表:,但分桶的判断字段0值、空值过多,这些空值都由一个reduce处理,非常慢
group by:group by维度过小,某值的数量过多,处理某值的reduce非常耗时
count distinct,某特殊值过多,处理此特殊值的reduce非常耗时
原因:
- key分布不均匀
- 业务数据本身特性
- 建表是考虑不周
- 某些sql本身就有数据倾斜
现象:
- 任务进度长时间维持在99%,查看任务监控页面,只发现有少量(1个或几个)reduce子任务未完成。因为其处理的数据量和其他reduce差异过大。
- 单一reduce的记录数与平均记录数差异过大,通常可能达到3倍甚至更多。最长时长远远大于平均时长。
解决方案
参数调节
- hive.map.aggr = true
- hive.groupby,skewindata = true
map端部分聚合,相当于combiner
有数据倾斜的时候进行负载均衡,当选型设置为true,生成的查询计划会有两个MR Job。
- 第一个mr job中,map的输出结果会随机的分布到reduce中,每个reduce做部分聚合操作,并输出结果。这样处理的结果是相同的group by key有可能被分发到不同的reduce中,从而达到负载均衡的目的。
- 第二个mr job再根据预处理的数据结果按照 group by key分布到reduce中(这个过程保证相同的key被分布到同一个reduce中)最后完成最终的聚合操作。
sql语句调节
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 如何join:
关于驱动表的选取,选用join key分布最均匀的表最为驱动表,做好列裁剪和filter操作,以达到两表做join的时候,数据量相对较少。
使用map join让小的维度表(1000条以下记录数)先进内存,在map端完成reduce
大表join大表:
把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于nul值关联不上,处理后并不影响最终结果。
count distinct大量相同特殊值:
count distinct时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果+1
group by维度过小:
采用sum() group by的方式来替换count(distinct)完成计算
特殊情况特殊处理:
业务逻辑优化效果一般的情况下,可以将数据倾斜的数据单独拿出来处理,最后union回去。

