大数据面试之Hive常见题目
1. Hive的架构
1、重点四个器:解释器(SQL Parser)、Driver:编译器(Compiler),优化器(Optimizer),执行器(Executor)
相关解释:
Driver 组件完成 HQL 查询语句从词法分析,语法分析,编译,优化,以及生成逻辑执行计划的生成。生成的逻辑执行计划存储在 HDFS 中,并随后由 MapReduce 调用执行
Hive 的核心是驱动引擎, 驱动引擎由四部分组成:
(1) 解释器(SQL Parser):解释器的作用是将 Hive QL 语句转换为抽象语法树(AST)
(2) 编译器(Compiler):编译器是将语法树编译为逻辑执行计划
(3) 优化器(Query Optimizer):优化器是对逻辑执行计划进行优化
(4) 执行器(Executor):执行器是调用底层的运行框架执行逻辑执行计划
2、执行流程
Hive QL 通过命令行或者客户端提交,经过 Compiler 编译器,运用 MetaStore 中的元数据进行类型检测和语法分析,生成一个逻辑方案(Logical Plan),然后通过的优化处理,产生一个 MapReduce 任务
2. Hive和数据库比较
3. 内部表和外部表的区别
主要如下:
1、删除数据时
内部表:元数据和原始数据,全部删除
外部表:只删除元数据
2、在公司生产环境下,什么时候创建内部表,什么时候创建外部表?
在公司中绝大多数场景都是外部表;
一般情况自己使用的临时表,才会创建内部表。
4. 4个By区别
1)Order By:全局排序,只有一个Reducer。给所有的数据都聚合到这里Reducer里面进行处理,这种情况要慎用,所有企业数据过来很容易就OOM了;
2)Sort By:分区内有序;
3)Distrbute By:分区,类似MR中Partition,结合Sort By使用。
4) Cluster By:当Distribute By和Sort By字段相同时,可以使用Cluster By方式。Cluster By除了具有Distribute By的功能外还兼具Sort By的功能。但是排序只能是升序排序,不能指定排序规则为ASC或者DESC。
在生产环境中Order By用的比较少,容易导致OOM。
在生产环境中Sort By + Distrbute By用的多。
5. 系统函数
1、date_add、date_sub函数(加减日期)
2、last_day函数(求当月最后一天日期)
3、next_day函数(周指标相关)
4、date_format函数(根据格式整理日期)
5、get_json_object函数 (解析json函数)
6、concat 拼接函数
7、explode 炸裂函数
8、NVL(表达式1,表达式2) 判断空的函数。如果表达式1为空值,NVL返回值为表达式2的值,否则返回表达式1的值。
6. 自定义UDF、UDTF函数
1、在项目中是否自定义过UDF、UDTF函数,以及用他们处理了什么问题,及自定义步骤?
(1)UDF函数是一行输入,一行输出,有些类似于map,是对结构进行变换;项目中用UDF函数解析公共字段。
UDTF函数是一行输入,多行输出,类似于flatmap ;项目中用UDTF函数解析事件字段。
UDAF函数是多行输入,一行输出,类似于sum等聚合函数。企业中用的少,使用步骤比较繁琐。
(2)自定义UDF
老版本方式:继承UDF,重写evaluate方法。
新版本方式:继承自GenericUDF,重写3个方法:其中最重要的一个方法就是evaluate方法。
(3)自定义UDTF:继承自GenericUDTF,重写3个方法:initialize(自定义输出的列名和类型),process(处理的核心逻辑,将结果返回forward(result)),close
(4)自定义函数写完之后,打包上传到HDFS的干净的路径,然后在Hive的客户端进行注册即可使用。
(5)注意自定义函数在Shell脚本中使用的时候,要在函数的前面加上库名,否则会报函数找不到的问题。
2、为什么要自定义UDF/UDTF?
自定义函数,可以自己埋点日志,方便打印日志,方便查看出错信息或者数据异常信息,方便调试。
另外极少数的情况可能内置函数不能处理业务逻辑。
7. 窗口函数
1、 OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化
(1)CURRENT ROW:当前行
(2)n PRECEDING:往前n行数据
(3) n FOLLOWING:往后n行数据
(4)UNBOUNDED:起点,UNBOUNDED PRECEDING 表示从前面起点, UNBOUNDED FOLLOWING表示到后面终点
(5) LAG(col,n):往前第n行数据
(6)LEAD(col,n):往后第n行数据
(7) NTILE(n):把有序分区中的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回此行所属的组的编号。注意:n为int类型。
2、Rank
(1)RANK() 排序相同时会重复,总数不会变
(2)DENSE_RANK() 排序相同时会重复,总数会减少
(3)ROW_NUMBER() 会根据顺序计算
8. Hive数据倾斜
1、数据倾斜
某些任务的运行市场源源大于其他的任务运行时长,比如在有的企业中定义时间是20倍以上,就认为发生了数据倾斜。
2、怎么产生的数据倾斜
(1)不同数据类型关联产生数据倾斜
情景:比如用户表user中user_id字段为int,log表中user_id字段string类型。当按照user_id进行两个表的Join操作时候比较容易发生数据倾斜。
解决方式:把数字类型转换成字符串类型
select * from user a
left outer join log b
on a.user_id = cast(b.user_id as string)
(2)空值分布也易发生数据倾斜
比如一些爬取数据,可能爬取过来的很多核心字段都是空的,这个时候比如聚合join的话,大量空值数据进入到一个reduce中去,导致数据倾斜。
解决办法:
如果不需要的异常值,可以直接给空值过滤掉。或者自定义分区,将为空的key转变为字符串加随机数或纯随机数,将因空值而造成倾斜的数据分布到多个Reducer。
小总结:对于异常值如果不需要的话,最好是提前在where条件里过滤掉,这样可以使计算量大幅度减少。
3、还有一些常见的数据倾斜现象及解决方法
(1)group by id 的时候产生数据倾斜
①按照id分组计算count值。 有单个key的,有多个key的
②单个key
加随机数,双重聚合。
配置参数,双重聚合 ,可以使用参数: set hive.groupby.skewindata = true; 这个参数就是设置自动二次聚合。
过滤出来这个key单独处理。
③多个key
增加Reducer的个数,一定程度上解决了问题。
自定义分区器。
加随机数,双重聚合。
(2)Join on关联字段
①大表 Join 小表
开启MapJoin,这个时候使用MapJoin给小表缓存到Map阶段,进行处理,避免了数据倾斜。
②大表 Join 大表
转化为多个 大表Join 小表
比如说给a表加上溢写随机数分开,给b表进行扩容。
9. Hive优化
见单独的 Hive优化 文档
10 Hive相关的补充性知识
分隔符字段提前处理、元数据备份等等。