hive面试题

1,137 阅读7分钟

1. hive 内部表和外部表的区别?

  • 未被external修饰的是内部表(managed table),被external修饰的为外部表(external table);
  • 内部表数据由Hive自身管理,外部表数据由HDFS管理;
  • 内部表数据存储的位置是hive.metastore.warehouse.dir(默认:/user/hive/warehouse),外部表数据的存储位置由自己制定(如果没有LOCATION,Hive将在HDFS上的/user/hive/warehouse文件夹下以外部表的表名创建一个文件夹,并将属于这个表的数据存放在这里);
  • 删除内部表会直接删除元数据(metadata)及存储数据;删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除;
  • 对内部表的修改会将修改直接同步给元数据,而对外部表的表结构和分区进行修改,则需要修复(MSCK REPAIR TABLE table_name;)
  • 修改外部表想要生效,需要先把外部表转内部表,然后修改,再转外部表。

2. hive 是如何实现分区的?

建表语句; create table tablename (id) partitioned by (dt string)

增加分区: alter table tablenname add partition (dt = ‘2016-03-06’)

删除分区: alter table tablename drop partition (dt = ‘2016-03-06’)

3. Hive 有哪些方式保存元数据,各有哪些优缺点?

存储于 derby数据库,此方法只能开启一个hive客户端,不推荐使用

存储于mysql数据库中,可以多客户端连接,推荐使用

4. hive中order by、distribute by、sort by和cluster by的区别和联系

order by

order by 会对数据进行全局排序,和oracle和mysql等数据库中的order by 效果一样,它只在一个reduce中进行所以数据量特别大的时候效率非常低。 而且当设置 :set hive.mapred.mode=strict的时候不指定limit,执行select会报错,如下: LIMIT must also be specified。

sort by

sort by 是单独在各自的reduce中进行排序,所以并不能保证全局有序,一般和distribute by 一起执行,而且distribute by 要写在sort by前面。 如果mapred.reduce.tasks=1和order by效果一样,如果大于1会分成几个文件输出每个文件会按照指定的字段排序,而不保证全局有序。 sort by 不受 hive.mapred.mode 是否为strict ,nostrict 的影响。

distribute by

DISTRIBUTE BY 控制map 中的输出在 reducer 中是如何进行划分的。使用DISTRIBUTE BY 可以保证相同KEY的记录被划分到一个Reduce 中。

cluster by

distribute by 和 sort by 合用就相当于cluster by,但是cluster by 不能指定排序为asc或 desc 的规则,只能是升序排列。

5. hive 中的压缩格式 RCFile、 TextFile、 SequenceFile 各有什么区别?

TextFile:默认格式,数据不做压缩,磁盘开销大,数据解析开销大

SequenceFile:Hadoop API提供的一种二进制文件支持,使用方便,可分割,可压缩,支持三种压缩,NONE,RECORD,BLOCK。

RCFILE:是一种行列存储相结合的方式。首先,将数据按行分块,保证同一个 record 在同一个块上,避免读一个记录读取多个block。其次,块数据列式存储,有利于数据压缩和快速的列存取。数据加载的时候性能消耗大,但具有较好的压缩比和查询响应。

6. hive 如何优化?

  • join 优化,尽量将小表放在 join 的左边,如果一个表很小可以采用 mapjoin。
  • 排序优化,order by 一个 reduce 效率低,distirbute by +sort by 也可以实现全局排序。
  • 使用分区,查询时可减少数据的检索,从而节省时间。

7. 海量数据分布在100台电脑中,如何高效统计出这批数据的top10

方案1:

  1. 在每台电脑上求出TOP10,可以采用包含10个元素的堆完成(TOP10小,用最大堆,TOP10大,用最小堆)。
  2. 比如求TOP10大,我们首先取前10个元素调整成最小堆,如果发现,然后扫描后面的数据,并与堆顶元素比较,如果比堆顶元素大,那么用该元素替换堆顶,然后再调整为最小堆。
  3. 最后堆中的元素就是TOP10大 方案2
  4. 求出每台电脑上的TOP10后,然后把这100台电脑上的TOP10组合起来,共1000个数据
  5. 再利用上面类似的方法求出TOP10就可以了。

8. row_number()、rank()、dense_rank() 区别

ROW_NUMBER()函数作用就是将select查询到的数据进行排序,每一条数据加一个序号,他不能用做于学生成绩的排名,一般多用于分页查询。 RANK()函数,顾名思义排名函数,可以对某一个字段进行排名,这里为什么和ROW_NUMBER()不一样那,ROW_NUMBER()是排序,当存在相同成绩的学生时,ROW_NUMBER()会依次进行排序,他们序号不相同,而Rank()则不一样出现相同的,他们的排名是一样的。 DENSE_RANK()函数也是排名函数,和RANK()功能相似,也是对字段进行排名。

9. hive常用开窗函数

开窗函数一般用于数据分析,计算基于组的某种聚合值。

跟聚合函数的区别在于:对于每个组返回多行,而聚合函数对于每个组只返回一行。 开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化!

基础结构:分析函数(如:sum(),max(),row_number()...) + 窗口子句(over函数)

例如:sum() over(partition by user_id order by order_time desc) over函数写法: over(partition by cookieid order by createtime) 先根据cookieid字段分区,相同的cookieid分为一区,每个分区内根据createtime字段排序(默认升序)

注:不加 partition by 的话则把整个数据集当作一个分区,不加 order by的话会对某些函数统计结果产生影响,如sum()

分析函数有:avg(),min(),max(),sum()

排序函数:row_number(), rank(), dense_rank()

10. 本地模式

大多数的 Hadoop Job 是需要 Hadoop 提供的完整的可扩展性来处理大数据集的。不过,有时 Hive 的输入数据量是非常小的。在这种情况下,为查询触发执行任务消耗的时间可能会比实际 job 的执行时间要多的多。对于大多数这种情况,Hive 可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显被缩短。

用户可以通过设置 hive.exec.mode.local.auto 的值为 true,来让 Hive 在适当的时候自动启动这个优化。

set hive.exec.mode.local.auto=true; //开启本地 mr
//设置 local mr 的最大输入数据量,当输入数据量小于这个值时采用 local mr 的方式,默认134217728,即 128M
set hive.exec.mode.local.auto.inputbytes.max=50000000;
//设置 local mr 的最大输入文件个数,当输入文件个数小于这个值时采用 local mr 的方式,默
认为 4
set hive.exec.mode.local.auto.input.files.max=10;

11. HQL转换成MR任务流程

1. 进入程序,利用Antlr框架定义HQL的语法规则,对HQL完成此法语法解析,将HQL转换为AST(抽象语法树);
2. 遍历AST, 抽象出查询的基本组成单元QueryBlock(查询块),可以理解为最小的查询执行单元;
3. 遍历QueryBlock,将其转换为OperatorTree(操作树,也就是逻辑执行计划),可以理解为不可拆分的一个逻辑执行单元;
4. 使用逻辑优化器对OperatorTree(操作树)进行逻辑优化。例如合并不必要的Reduce,减少shuffle数据量;
5. 遍历OperatorTree,转换为TaskTree。也就是翻译为MR任务的六层,将逻辑执行计划转换为物理执行计划;
6. 使用武力优化器对TaskTree进行武力优化;
7. 生成最终的执行计划,提交任务到Hadoop集群运行。