大数据最全面试题整理-hive篇
- 导语
- 基础问题:
- hive与传统数据库的区别
- hive的数据类型
- 元数据保存方式
- 内部表和外部表的区别
- 分区表和分桶表的区别
- 简述hive的存储格式
- hive如何将Hql转化为MapReduce
- hive排序函数的区别
- UDF相关内容
- 故障排查与调优
- 数据倾斜与优化
- 性能优化
导语
本专栏博文会整理日常工作与面试中最常用到的大数据相关组件与Java语言的架构、概念、知识点,方便大家进行查阅。
涉及到的面试题以及答案均为博主搜罗整理,并加上自己的理解编写而成。同时博主会在部分题目的下方添加管遇此题深入理解的博文连接,方便读者的深入理解。
希望大家可以通过此篇博文对于大数据相关概念有一个更深入的理解
还有哪些想看的面试题,读者可以在评论区补充,博主会在一天内进行更新!!!
最后预祝大家新的一年升职加薪,工资涨涨涨!
基础问题:
hive与传统数据库的区别
- 表数据验证:传统数据库是写模式,hive是读模式。传统数据库在写入数据的时候就去检查数据格式,hive在读取数据的时候检查。因此,写时模式,查询快,读时模式数据加载快。
- hive不支持实时处理,并且对索引支持较弱。
- hive不支持行级插入、更新、删除和事务。
- 索引。Hive没有,数据库有
- 执行。Hive是MapReduce,数据库是Executor
- 可扩展性。Hive高,数据库低
- 数据规模。Hive大,数据库小
- 数据存储位置。Hive是建立在Hadoop之上的,所有的Hive的数据都是存储在HDFS中的。而数据库则可以将数据保存在块设备或本地文件系统中。
- 数据格式。Hive中没有定义专门的数据格式,由用户指定,需要指定三个属性:列分隔符,行分隔符,以及读取文件数据的方法。数据库中,存储引擎定义了自己的数据格式。所有数据都会按照一定的组织存储。
- 数据更新。Hive的内容是读多写少的,因此,不支持对数据的改写和删除,数据都在加载的时候中确定好的。数据库中的数据通常是需要经常进行修改。
- 执行延迟。Hive在查询数据的时候,需要扫描整个表(或分区),因此延迟较高,只有在处理大数据是才有优势。数据库在处理小数据是执行延迟较低。
hive的数据类型
原始数据类型
- 整型
TINYINT — 微整型,只占用1个字节,只能存储0-255的整数。
SMALLINT– 小整型,占用2个字节,存储范围–32768 到 32767。
INT– 整型,占用4个字节,存储范围-2147483648到2147483647。
BIGINT– 长整型,占用8个字节,存储范围-263到263-1。 - 布尔型
BOOLEAN — TRUE/FALSE - 浮点型
FLOAT– 单精度浮点数。
DOUBLE– 双精度浮点数。 - 字符串型
STRING– 不设定长度。
复合数据类型
- Structs:一组由任意数据类型组成的结构。比如,定义一个字段C的类型为STRUCT {a INT; b STRING},则可以使用a和C.b来获取其中的元素值;
- Maps:一组无序的键/值对。键的类型必须是原子的,值可以是任何类型,同一个映射的键的类型必须相同,值得类型也必须相同
- Arrays:一组有序字段。字段的类型必须相同
元数据保存方式
hive是建立在hadoop之上的数据仓库,一般用于对大型数据集的读写和管理,存在hive里的数据实际上就是存在HDFS上,都是以文件的形式存在,不能进行读写操作,所以我们需要元数据或者说叫schem来对hdfs上的数据进行管理。主要有以下三种方式:
- 内嵌模式:将元数据保存在本地内嵌的derby数据库中,内嵌的derby数据库每次只能访问一个数据文件,也就意味着它不支持多会话连接。
- 本地模式:将元数据保存在本地独立的数据库中(一般是mysql),这可以支持多会话连接。
- 远程模式:把元数据保存在远程独立的mysql数据库中,避免每个客户端都去安装mysql数据库。
内部表和外部表的区别
- 内部表: 未被external修饰的是内部表,建表时默认创建内部表。内部表数据由Hive自身管理。删除内部表会直接删除元数据(metadata)及存储数据;对内部表的修改会将修改直接同步给元数据。
- 外部表:被external修饰的为外部表(external table);外部表数据由HDFS管理;删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除;
分区表和分桶表的区别
- 分区表,Hive 数据表可以根据某些字段进行分区操作,细化数据管理,让部分查询更快,不同分区对应不同的目录;
- 分桶表:表和分区也可以进一步被划分为桶,分桶是相对分区进行更细粒度的划分。分桶将整个数据内容按照某列属性值的hash值进行区分,不同的桶对应不同的文件。
简述hive的存储格式
- TextFile
TextFile文件不支持块压缩,默认格式,数据不做压缩,磁盘开销大,数据解析开销大。 - SequenceFile格式
SequenceFile是Hadoop API 提供的一种二进制文件,它将数据以的形式序列化到文件中。这种二进制文件内部使用Hadoop 的标准的Writable 接口实现序列化和反序列化。它与Hadoop API中的MapFile 是互相兼容的。Hive 中的SequenceFile 继承自Hadoop API 的SequenceFile,不过它的key为空,使用value 存放实际的值, 这样是为了避免MR 在运行map 阶段的排序过程。 - RCFile
Record Columnar的缩写。是Hadoop中第一个列文件格式。能够很好的压缩和快速的查询性能,但是不支持模式演进。通常写操作比较慢,比非列形式的文件格式需要更多的内存空间和计算量。
RCFile是一种行列存储相结合的存储方式。首先,其将数据按行分块,保证同一个record在一个块上,避免读一个记录需要读取多个block。其次,块数据列式存储,有利于数据压缩和快速的列存取。 - ORCFile
存储方式:数据按行分块 每块按照列存储 ,压缩快 快速列存取,效率比rcfile高,是rcfile的改良版本,相比RC能够更好的压缩,能够更快的查询,但还是不支持模式演进。
hive如何将Hql转化为MapReduce
- 解释器完成词法、语法和语义的分析以及中间代码生成,最终转换成抽象语法树;
- 编译器将语法树编译为逻辑执行计划;
- 逻辑层优化器对逻辑执行计划进行优化,由于Hive最终生成的MapReduce任务中,Map阶段和Reduce阶段均由OperatorTree组成,所以大部分逻辑层优化器通过变换OperatorTree,合并操作符,达到减少MapReduce Job和减少shuffle数据量的目的;
- 物理层优化器进行MapReduce任务的变换,生成最终的物理执行计划;
- 执行器调用底层的运行框架执行最终的物理执行计划。
hive排序函数的区别
- 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 的规则,只能是升序排列。
UDF相关内容
UDF(User-Defined Functions)即是用户自定义的hive函数。当 Hive 自带的函数并不能完全满足业务的需求,这时可以根据具体需求自定义函数。UDF 函数可以直接应用于 select 语句,对查询结构做格式化处理后,再输出内容。
Hive 自定义函数包括三种:
- UDF: one to one ,进来一个出去一个,row mapping, 如:upper、substr函数;
- UDAF(A:aggregation): many to one,进来多个出去一个,row mapping,如sum/min;
- UDTF(T:table-generating):one to mang,进来一个出去多行,如 lateral view 与 explode 。
故障排查与调优
数据倾斜与优化
什么是数据倾斜?
数据倾斜就是数据的分布不平衡,某些地方特别多,某些地方又特别少,导致在处理数据的时候,有些很快就处理完了,而有些又迟迟未能处理完,导致整体任务最终迟迟无法完成,这种现象就是数据倾斜。
发生数据倾斜的原因
- key分布不均匀;
- 数据本身的特性,原本按照日期进行分区,如果在特定日期数据量剧增,就有可能造成倾斜;
- 建表时考虑不周,分区设置不合理或者过少;
- 某些 HQL 语句本身就容易产生数据倾斜,如 join。
以下操作可能会导致数据倾斜
- join
大小表join的时候,其中一个较小表的key集中,这样分发到某一个或者几个的Reduce上的数据就可能远高于平均值;
两张大表join的时候,如果有很多0值和空值,那么这些0值或者空值就会分到一个Reduce上进行处理;
join的时候,不同数据类型进行关联,发生类型转换的时候可能会产生null值,null值也会被分到一个Reduce上进行处理; - group by
进行分组的字段的值太少,造成Reduce的数量少,相应的每个Reduce的压力就大; - count distinct
count distinct的时候相同的值会分配到同一个Reduce上,如果存在特殊的值太多也会造成数据倾斜。
解决方法