Hive⾯试题总结
⽂章⽬录
前⾔
根据参考的各⼤⾯试题进⾏总结,并且不断更新。希望能帮助⼤家
⼀、Hive
1. Hive 表关联查询,如何解决数据倾斜的问题?
1)倾斜原因:
map 输出数据按 key Hash 的分配到 reduce 中,由于 key 分布不均匀、业务数据本⾝的特、
建表时考虑不周、等原因造成的 reduce 上的数据量差异过⼤。
(1)key 分布不均匀;
(2)业务数据本⾝的特性;
(3)建表时考虑不周;
(4)某些 SQL 语句本⾝就有数据倾斜;
如何避免:对于 key 为空产⽣的数据倾斜,可以对其赋予⼀个随机值。
2)解决⽅案
(1)参数调节:
hive.map.aggr = true
有数据倾斜的时候进⾏负载均衡,当选项设定位 true,⽣成的查询计划会有两个 MR Job。第⼀个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的Reduce中,从⽽达到负载均衡的⽬的;第⼆个 MR Job 再根据预处理的数据结果按照 Group By Key分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同⼀个 Reduce 中),最后完成最终的聚合操作。
(2)SQL 语句调节:
① 选⽤ join key 分布最均匀的表作为驱动表。做好列裁剪和 filter 操作,以达到两表做join 的时候,数据量相对变⼩的效果。
② ⼤⼩表 Join:
使⽤ map join 让⼩的维度表(1000 条以下的记录条数)先进内存。在 map 端完成 reduce.
③ ⼤表 Join ⼤表:
把空值的 key 变成⼀个字符串加上随机数,把倾斜的数据分到不同的 reduce 上,由于null 值关联不上,处理后并不影响最终结果。
④ count distinct ⼤量相同特殊值:
count distinct 时,将值为空的情况单独处理,如果是计算 count distinct,可以不⽤处理,直接过滤,在最后结果中加 1。如果还有其他计算,需要进⾏ group by,可以先将值为空的记录单独处理,再和其他计算结果进⾏ union。
2. 谈⼀下 Hive 的特点,Hive 和 RDBMS 有什么异同
Hive 和数据库除了拥有类似的查询语⾔,再⽆类似之处。
1)数据存储位置
Hive 存储在 HDFS 。数据库将数据保存在块设备或者本地⽂件系统中。
2)数据更新
Hive中不建议对数据的改写。⽽数据库中的数据通常是需要经常进⾏修改的。
3)执⾏延迟
Hive 执⾏延迟较⾼。数据库的执⾏延迟较低。当然,这个是有条件的,即数据规模较⼩,当数据规模⼤到超过数据库的处理能⼒的时
候,Hive的并⾏计算显然能体现出优势。
4)数据规模
Hive⽀持很⼤规模的数据计算;数据库可以⽀持的数据规模较⼩。
3. 请说明 hive 中 Sort By,Order By,Cluster By,Distrbute By各代表什么意思
order by:会对输⼊做全局排序,因此只有⼀个 reducer(多个 reducer ⽆法保证全局有序)。只有⼀个 reducer,会导致当输⼊规模较⼤时,需要较长的计算时间。
sort by:不是全局排序,其在数据进⼊ reducer 前完成排序。
distribute by:按照指定的字段对数据进⾏划分输出到不同的 reduce 中。
cluster by:除了具有 distribute by 的功能外还兼具 sort by 的功能。
4. Hive 有哪些⽅式保存元数据,各有哪些特点
Hive ⽀持三种不同的元存储服务器,分别为:内嵌式元存储服务器、本地元存储服务器、远程元存储服务器,每种存储⽅式使⽤不同的配置参数。内嵌式元存储主要⽤于单元测试,在该模式下每次只有⼀个进程可以连接到元存储,Derby 是内嵌式元存储的默认数据库。在本地模式下,每个 Hive 客户端都会打开到数据存储的连接并在该连接上请求 SQL 查询。在远程模式下,所有的 Hive 客户端都将打开⼀个到元数据服务器的连接,该服务器依次查询元数据,元数据服务器和客户端之间使⽤ Thrift 协议通信。
5. Hive 内部表和外部表的区别
创建表时:创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径, 不对数据的位置做任何改变。删除表时:在删除表的时候,内部表的元数据和数据会被⼀起删除, ⽽外部表只删除元数据,不删除数据。这样外部表相对来说更加安全些,数据组织也更加灵活,⽅便共享源数据。
6. Hive 的 HSQL 转换为 MapReduce 的过程
过程描述如下:
SQL Parser:Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象 语法树AST Tree
Semantic Analyzer:遍历AST Tree,抽象出查询的基本组成单元QueryBlock
Logical plan:遍历QueryBlock,翻译为执⾏操作树OperatorTree
Logical plan optimizer:逻辑层优化器进⾏OperatorTree变换,合并不必要的ReduceSinkOperator,减少shuffle数据量
Physical plan:遍历OperatorTree,翻译为MapReduce任务
Logical plan optimizer:物理层优化器进⾏MapReduce任务的变换,⽣成最终的执⾏计划。
7. Hive 中的压缩格式TextFile、SequenceFile、RCfile 、ORCfile各有什么区别
1)TextFile
默认格式,存储⽅式为⾏存储,数据不做压缩,磁盘开销⼤,数据解析开销⼤。 可结合Gzip、Bzip2使⽤(系统⾃动检查,执⾏查询时⾃动解压),但使⽤这种⽅式,压缩后的⽂件不⽀持split,Hive不会对数据进⾏切分,从⽽⽆法对数据进⾏并⾏操作。并且在反序列化过程中,必须逐个字符判断是不是分隔符和⾏结束符,因此反序列化开销会⽐SequenceFile⾼⼏⼗倍
2)SequenceFile
SequenceFile是Hadoop API提供的⼀种⼆进制⽂件⽀持,,存储⽅式为⾏存储,其具有使⽤⽅便、可分割、可压缩的特点SequenceFile ⽀持三种压缩选择:NONE,RECORD,BLOCK。Record压缩率低,⼀般建议使⽤BLOCK压缩。优势是⽂件和hadoop api中的MapFile是相互兼容的
3)RCFile
4)ORCFile
存储⽅式:数据按⾏分块 每块按照列存储
压缩快:快速列存取效率⽐rcfile⾼,是rcfile的改良版本。
总结:相⽐TEXTFILE和SEQUENCEFILE,RCFILE由于列式存储⽅式,数据加载时性能消耗较⼤,但是具有较好的压缩⽐和查询响应数据仓库的特点是⼀次写⼊、多次读取,因此,整体来看,RCFILE相⽐其余两种格式具有较明显的优势。
8. Hive join 过程中⼤表⼩表的放置顺序
将最⼤的表放置在 JOIN 语句的最右边,或者直接使⽤/*+ streamtable(table_name) */指出。在编写带有 join 操作的代码语句时,应该将条⽬少的表/⼦查询放在 Join 操作符的左边。因为在 Reduce 阶段,位于 Join 操作符左边的表的内容会被加载进内存,载⼊条⽬较少的表可以有效减少 OOM(out of memory)即内存溢出。所以对于同⼀个 key 来说,对应的 value 值⼩的放前,⼤的放后,这便是“⼩表放前”原则。若⼀条语句中有多个 Join,依据 Join 的条件相同与否,有不同的处理⽅法。
9. 所有的Hive任务都会有MapReduce的执⾏吗
不是,从Hive0.10.0版本开始,对于简单的不需要聚合的类似SELECT from
LIMIT n语句,不需要起MapReduce job,直接通过Fetch task获取数据。
10. Hive 的函数:UDF、UDAF、UDTF 的区别
UDF: 单⾏进⼊,单⾏输出
UDAF: 多⾏进⼊,单⾏输出
UDTF: 单⾏输⼊,多⾏输出
11. 说说对 Hive 桶表的理解
分区针对的是数据的存储路径;分桶针对的是数据⽂件。
Hive分桶通俗点来说就是将表(或者分区,也就是hdfs上的⽬录⽽真正的数据是存储在该⽬录下的⽂件)中⽂件分成⼏个⽂件去存储。⽐如表buck(⽬录,⾥⾯存放了某个⽂件如sz.data)⽂件中本来是1000000条数据,由于在处理⼤规模数据集时,在开发和修改查询的阶段,如果能在数据集的⼀⼩部分数据上试运⾏查询,会带来很多⽅便,所以我们可以分4个⽂件去存储。
桶表是对数据进⾏哈希取值,然后放到不同⽂件中存储。数据加载到桶表时,会对字段取 hash 值,然后与桶的数量取模。把数据放到对应的⽂件中。物理上,每个桶就是表(或分区)⽬录⾥的⼀个⽂件,⼀个作业产⽣的桶(输出⽂件)和reduce 任务个数相同。桶表专门⽤于抽样查询,是很专业性的,不是⽇常⽤来存储数据的表,需要抽样查询时,才创建和使⽤桶表。
12. Hive ⾃定义 UDF 函数的流程
1)写⼀个类继承(org.apache.hadoop.hive.ql.)UDF 类;
2)覆盖⽅法 evaluate();
3)打 JAR 包;
4)通过 hive 命令将 JAR 添加到 Hive 的类路径:
hive> add jar /home/ubuntu/ToDate.jar;
5)注册函数:
hive> create temporary function xxx as ‘XXX’;
6)使⽤函数;
13. hive 有索引吗
Hive ⽀持索引,但是 Hive 的索引与关系型数据库中的索引并不相同,⽐如,Hive不⽀持主键或者外键。
Hive 索引可以建⽴在表中的某些列上,以提升⼀些操作的效率,例如减少
MapReduce 任务中需要读取的数据块的数量。在可以预见到分区数据⾮常庞⼤的情况下,索引常常是优于分区的。
虽然 Hive 并不像事物数据库那样针对个别的⾏来执⾏查询、更新、删除等操作。它更多的⽤在多任务节点的场景下,快速地全表扫描⼤规模数据。但是在某些场景下,建⽴索引还是可以提⾼ Hive 表指定列的查询速度。(虽然效果差强⼈意)
索引适⽤的场景
适⽤于不更新的静态字段。以免总是重建索引数据。每次建⽴、更新数据后,都要重建索引以构建索引表。
14. 数据建模⽤的哪些模型
星型模型
星形模式(Star Schema)是最常⽤的维度建模⽅式。星型模式是以事实表为中⼼,所有的维度表直接连接在事实表上,像星星⼀样。
星形模式的维度建模由⼀个事实表和⼀组维表成,且具有以下特点:
a. 维表只和事实表关联,维表之间没有关联;
b. 每个维表主键为单列,且该主键放置在事实表中,作为两边连接的外键;
c. 以事实表为核⼼,维表围绕核⼼呈星形分布;
雪花模型
雪花模式(Snowflake Schema)是对星形模式的扩展。雪花模式的维度表可以拥有其他维度表的,虽然这种模型相⽐星型更规范⼀些,但是由于这种模型不太容易理解,维护成本⽐较⾼,⽽且性能⽅⾯需要关联多层维表,性能也⽐星型模型要低。所以⼀般不是很常⽤。
星座模型
星座模式是星型模式延伸⽽来,星型模式是基于⼀张事实表的,⽽星座模式是基于多张事实表的,⽽且共享维度信息。前⾯介绍的两种维度建模⽅法都是多维表对应单事实表,但在很多时候维度空间内的事实表不⽌⼀个,⽽⼀个维表也可能被多个事实表⽤到。在业务发展后期,绝⼤部分维度建模都采⽤的是星座模式
多表查询sql语句面试题15. 为什么要对数据仓库分层
1. ⽤空间换时间,通过⼤量的预处理来提升应⽤系统的⽤户体验(效率),因此数据仓库会存在⼤量冗余的数据。
2. 如果不分层的话,如果源业务系统的业务规则发⽣变化将会影响整个数据清洗过程,⼯作量巨⼤。
3. 通过数据分层管理可以简化数据清洗的过程,因为把原来⼀步的⼯作分到了多个步骤去完成,相当于把⼀个复杂的⼯作拆成了多个简
单的⼯作,把⼀个⼤的⿊盒变成了⼀个⽩盒,每⼀层的处理逻辑都相对简单和容易理解,这样我们⽐较容易保证每⼀个步骤的正确性,当数据发⽣错误的时候,往往我们只需要局部调整某个步骤即可。
⼆、Hive优化
hive调优是⽐较⼤的专题,需要结合实际的业务,数据的类型,分布,质量状况等来实际的考虑如何进⾏系统性的优化,hive底层是mapreduce,所以hadoop调优也是hive调优的⼀个基础,hvie调优可以分为⼏个模块进⾏考虑,数据的压缩与存储,sql的优化,hive参数的优化,解决数据的倾斜等。
1. Fetch抓取
Fetch抓取是指,Hive中对某些情况的查询可以不必使⽤MapReduce计算。例如:SELECT * FROM
employees;在这种情况下,Hive可以简单地读取employee对应的存储⽬录下的⽂件,然后输出查询结果到控制台在hive-
2. 本地模式
⼤多数的Hadoop Job是需要Hadoop提供的完整的可扩展性来处理⼤数据集的。不过,有时Hive的输⼊数据量是⾮常⼩的。在这种情况下,为查询触发执⾏任务时消耗可能会⽐实际job的执⾏时间要多的多。对于⼤多数这种情况,Hive可以通过本地模式在单台机器上处理所有的任务。对于⼩数据集,执⾏时间可以明显被缩短 。⽤户可以通过设置de.local.auto的值为true,来让Hive在适当的时候⾃动启动这个优化
3. 表的优化
(1) ⼩表、⼤表join
将key相对分散,并且数据量⼩的表放在join的左边,这样可以有效减少内存溢出错误发⽣的⼏率;再进⼀步,可以使⽤Group让⼩的维度表(1000条以下的记录条数)先进内存。在map端完成reduce
实际测试发现:新版的hive已经对⼩表JOIN⼤表和⼤表JOIN⼩表进⾏了优化。⼩表放在左边和右边已经没有明显区别
(2) ⼤表Join⼩表
有时join超时是因为某些key对应的数据太多,⽽相同key对应的数据都会发送到相同的reducer上,从⽽导致内存不够。此时我们应该仔细分析这些异常的key,很多情况下,这些key对应的数据是异常数据,我们需要在SQL语句中进⾏过滤。例如key对应的字段为空
(3) Group By
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论