Hive
Hive是什么
hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。
Hive特点
- 不能实时查询,适合做离线分析
- 解释器,编译器,优化器等。 把SQL语句解释为底层的MRjob。
原理
- 用户访问接口。用户接口主要有三个:CLI命令行模式,Client 和 WUI。其中最常用的是CLI,Cli启动的时候,会同时启动一个Hive副本。
- Hive元数据管理服务器,首先会接受客户端的指令,但是不能直接转换为MRjob。Metastore是元数据存储数据库,单独搭建保留在一个服务器上
- 解释器、编译器、优化器完成HQL查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在HDFS中,并在随后有MapReduce调用执行。
- Hive的数据存储在HDFS中,大部分的查询、计算由MapReduce完成(包含*的查询,比如select * from tbl不会生成MapRedcue任务)。元数据存放在metastore
面试
内外表的区别 external
| 内部表 | 外部表 |
|---|---|
| 内部先有表,再加载数据,上传到HDFS。 | 先有数据在创建表去匹配,并在在建表结尾有 location ‘HDFS PATH’,创建的时候直接带入数据 |
| 内部表数据由Hive自身管理 | 外部表数据由HDFS管理; |
| 删除内部表会直接删除元数据(metadata)及存储数据 | 删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除; |
Hive静态分区
- Hive静态分区,属于元数据 相当于加了条件,提升索引效率。
- hadoop分区 map就开始了,目的是为了分布式并行时释放压力。
- 按照指定目录分批存储数据。
- 必须在表定义时指定对应的partition字段
- partitioned by (字段 字段类型);必须出现在format前面。
注意:分区字段必须是没有出现过的字段,分区是创建表的时候设定好的。
创建表
1 | create [external] table table_name( |
hive和关系型数据库(RDMBS)的区别
| 比较项 | RDMBS | hive |
|---|---|---|
| ANSI SQL | 支持 | 不支持 |
| 更新 | 支持 | 不支持(需要打开事务) |
| 事务 | 支持 | 不支持 |
| 模式 | 写模式 | 读模式 |
| 数据保存 | 本地文件系统 | HDFS |
| 延时 | 低(支持实时查询) | 高(用于离线分析) |
| 子查询 | 完全支持 | 只能在from中使用 |
| 可扩展性 | 低 | 高 |
| 数据规模 | 小 | 大 |
Hive中数据倾斜问题
原因:
- key分布不均匀
- hive分区设计问题
- 查询的时候,join导致
如何避免数据的倾斜:
打散key,使用随机的key
①hive.map.aggr = true。②hive.groupby.skewindata = true。使用这两个参数。
- 当选项设定位true,生成的查询计划会有两个MR Job
- 第一个MR Job中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的
- 第二个MR Job再根据预处理的数据结果按照Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个Reduce中),最后完成最终的聚合操作。
SQL语句的调节
- 选用join key分布最均匀的表作为驱动表。
- 大小表join的时候,让维度较小的表先进内存。
- 大表join的时候,把空值的key变成一个字符串加上一个随机数,把倾斜的数据分到不同的reduce上。(感觉是解决空值太多的数据倾斜)
- count distinct大量相同特殊值。
Hive中sort by、order by、cluster by、distribute by的区别
- sort by:不是全局排序,其在数据进入reducer前完成排序。
- order by:会对输入做全局排序,因此只有一个reducer,如果有多个reducer无法保证全局的排序。计算规模较大,时间可能会很长。
- cluster by:除了具有distribute by的功能,还具有了sort by的功能。
- distribute by:按照指定的字段对数据进行划分输出到不同的reduce中。
有疑问??cluster by并不明确作用?
Hive中的三种自定义函数
- UDF:单行进入,多行输出。
- UDAF:多行进入,单行输出。
- UDTF:多行进入,多行输出。
Hive的优化
- Group by:默认情况下,map阶段同一key的数据会发给一个reduce,当一个key数据过大就会倾斜,并不是所有的聚合操作都需要reduce端完成,很多聚合操作都可以现在map端进行部分聚合,最后在reduce端得出最终结果。(1)、开启在map端聚合:hive.map.aggr = true。(2)、在map端进行聚合操作的条目数:hive.groupby.mapaggr.checkinterval = 100000。(3)、有数据倾斜的时候进行负载均衡:hive.groupby.skewindata = true。
- count dinstinc去重:大的数据集先用count distinct查找重复的字段,然后用group by再去重。
- 动态分区调整:(1)、开启动态分区:hive.exec.dynamic.partition=true。(2)、设置为非严格模式:hive.exec.dynamic.partiton.mode = nostrict。(3)、实操:创建分区表、加载数据到分区表中、创建目标分区、设置动态分区、查看目标分区表的分区情况。
- 小文件进行合并:在map执行之前合并小文件,减少map的数量,设置 set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat。
