大数据面试题汇总之Hive 一、Hive是什么?跟数据仓库区别? 可回答:1)说下对Hive的了解;2)介绍下Hive 参考答案 Hive是由Facebook开源用于解决海量结构化日志的数据统计工具; Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能。 Hive的本质是将HQL转化成MapReduce程序 Hive处理的数据存储在HDFS – Hive分析数据底层的实现是MapReduce – 执行程序运行在Yarn上 数据仓库是为企业所有级别的决策制定过程,提供所有类型数据支持的战略集合。它是单个数据存储, 出于分析性报告和决策支持目的而创建。为需要业务智能的企业,提供指导业务流程改进、监视时间、 成本、质量以及控制。 数据仓库存在的意义在于对企业的所有数据进行汇总,为企业各个部门提供统一的, 规范的数据出口。 二、Hive架构是怎样的? 可回答:Hive的基本架构,角色,与HDFS的关系? 参考答案
有4个部分: 1 用户接口:Client 它包括:CLI(hive shell)、JDBC/ODBC(java访问hive)、WEBUI(浏览器访问hive) 2 数据:Metastore 数据包括:表名、表所属的数据库(默认是default)、表的拥有者、列/分区字段、表的类型(是否是外部表)、表的数据所在目录等; 默认存储在自带的derby数据库中,但是推荐使用MySQL存储Metastore。 因为这个derby数据库有缺点,它只能允许一个会话连接,只适合简单的测试。实际生产环境中不适用,不可能只允许一个会话连接,需要支持多用户会话,通常部署的时候会将hive的数据修改为保存在mysql中。 3 Hadoop集群 使用HDFS进行存储,使用MapReduce进行计算。 4 Driver:驱动器(下述流程也是SQL转化为MR的过程) 解析器(SQL Parser)将SQL字符串转换成抽象语法树AST对AST进行语法分析,比如表是否存在、字段是否存在、SQL语义是否有误 编译器(Physical Plan)将AST编译生成逻辑执行计划 优化器(Query Optimizer)对逻辑执行计划进行优化 执行器(Execution)把逻辑执行计划转换成可以运行的物理计划。对于Hive来说默认就是mapreduce任务 三、Hive内部表和外部表的区别? 参考答案 创建语句创建内部表create table if not exists myhive.stu3(id int, name string) row format delimited fields terminated by ‘\t’ stored as textfile location ‘/user/stu2’;创建外部表 外部表因为是指定其他的hdfs路径的数据加载到表当中来,所以hive表会认为自己不完全独占这份数据,所以删除hive表的时候,数据仍然存放在hdfs当中,不会删掉create external table myhive.teacher (t_id string,t_name string) row format delimited fields terminated by ‘\t’; 创建外部表的时候需要加上external关键字 location字段可以指定,也可以不指定指定就是数据存放的具体目录不指定就是使用默认目录 ==/user/hive/warehouse== 内部表与外部表的区别 1 建表语法的区别外部表在创建的时候需要加上==external==关键字 2 数据位置的区别创建内部表时:会将数据移动到数据仓库指向的路径;创建外部表时:仅记录数据所在路径,不对数据的位置做出改变; 3 删除表之后的区别内部表删除后,表的数据和真实数据都被删除了外部表删除后,仅仅只是把该表的数据删除了,真实数据还在,后期还是可以恢复出来 内部表与外部表的使用时机 内部表由于删除表的时候会同步删除HDFS的数据文件,所以确定如果一个表仅仅是你独占使用,其他人不适用的时候就可以创建内部表,如果一个表的文件数据,其他人也要使用,那么就创建外部表 一般外部表都是用在数据仓库的ODS层 内部表都是用在数据仓库的DW层 四、什么是分区表? 参考答案 如果hive当中所有的数据都存入到一个文件夹下面,那么在使用MR计算程序的时候,读取一整个目录下面的所有文件来进行计算,就会变得特别慢,因为数据量太大了。实际工作当中一般都是计算前一天的数据,所以我们只需要将前一天的数据挑出来放到一个文件夹下面即可,专门去计算前一天的数据。 这样就可以使用hive当中的分区表,通过分文件夹的形式,将每一天的数据都分成为一个文件夹,然后我们计算数据的时候,通过指定前一天的文件夹即可只计算前一天的数据。
也就是在文件系统上建立文件夹,把表的数据放在不同文件夹下面,加快查询速度! 五、什么是Hive数据倾斜、解决方案是什么?哪些操作可能引发数据倾斜? 参考答案 什么是数据倾斜? 数据倾斜主要表现在,map/reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个 reduce节点运行很慢,导致整个程序的处理时间很长,这是因为某一个key的条数比其他key多很多(有时 是百倍或者千倍之多),这条Key所在的reduce节点所处理的数据量比其他节点就大很多,从而导致某几 个节点迟迟运行不完。 从本质上来说,引发数据倾斜的原因主要有两种:一是任务种需要处理大量相同key的数据;二是任务读取不可分割的大文件。 解决方案? (1)参数调节: ①hive.map.aggr=true:Map 端部分聚合,相当于Combiner②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 中),最后完成最终的聚合操作。 (2)SQL语句调节: ①大小表Join:使用map join让小的维度表(1000条以下的记录条数) 先进内存,在map端完成join操作。正常情况下join是需要在reduce端执行的,通过map join可以实现在map端执行join操作,这样可以避免在shuffle的时候造成数据倾斜。 ②把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null值关联不上,处理后并不影响最终结果。 哪些操作可能引发数据倾斜? (1)group by产生数据倾斜: 当按照类型进行group by的时候,会将相同的group by 字段的reduce任务需要的数据拉取到同一个节点进行聚合, 而当其中每一组的数据量过大时,会出现其他组的计算已经完成而这里还没计算完成, 其他节点的一直等待这个节点的任务执行完成; (2)count(distinct)产生数据倾斜: 如果数据量非常大,执行如select a,count(distinct b) from t group by a;类型的SQL 时,会出现数据倾斜的问题。 (3)大表和小表 join产生数据倾斜: 当遇到一个大表和一个小表进行join操作时,大表数据分布不均匀时产生倾斜。 六、having 与 where 不同点(必背) 参考答案 1 where针对表中的列发挥作用,查询数据,而having针对查询结果中的列发挥作用,筛选数据; 2 where后面不能写分组函数,而having后面可以使用分组函数,并且having只用于group by分组统计语句; 七、sort By,order By,cluster By,distribute By 参考答案 order by:会对输入做全局排序,因此只有一个reducer(多个reducer无法保证全局有序)。只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。 sort by:不是全局排序,其在数据进入reducer前完成排序,也就是每个reducer内部进行排序,对全局结果集来说不是排序。 distribute by:按照指定的字段对数据进行划分输出到不同的reduce中。 cluster by:除了具有 distribute by 的功能外还兼具 sort by 的功能。 八、介绍下Hive的窗口函数,并举例说明 参考答案 窗口函数,也叫开窗函数,一般就是说的是over()函数,其窗口是由一个 OVER 子句 定义的多行记录~ 开窗函数一般分为两类:聚合开窗函数和排序开窗函数。 简单来说,窗口函数有以下功能: 1)同时具有分组和排序的功能 2)不减少原表的行数 相关函数如下: 九、Hive中用户自定义函数实现步骤,有哪些类型? 参考答案 1、如何构建用户自定义函数? ①继承UDF或者UDAF或者UDTF,实现特定的方法; ②将写好的类打包为jar,如hivefirst.jar; ③进入到Hive环境中,利用add jar 的形式注册该jar文件; ④注册函数,通过create temporary function 或create function 注册该函数 ⑤ 第五步:使用函数。 2、根据用户自定义函数类别分为以下三种: (1)UDF(User-Defined-Function)一进一出 (2)UDAF(User-Defined Aggregation Function)聚集函数,多进一出类似于:count/max/min (3)UDTF(User-Defined Table-Generating Functions)一进多出如lateral view explode() 十、Hive中表的存储格式有哪些? 参考答案 Hive支持的存储数的格式主要有:TEXTFILE(行式存储) 、SEQUENCEFILE(行式存储)、ORC(列式存储)、PARQUET(列式存储)。 1、列式存储和行式存储
上图左边为逻辑表,右边第一个为行式存储,第二个为列式存储。 那我们从这个图可以看出它俩的区别: 行存储的特点: 查询满足条件的一整行数据的时候,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。 列存储的特点: 因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。 也就是直接select * 时,行式存储效率比较高,select 某些字段时,列式存储效率比较高! 2、各存储格式的特点 TEXTFILE :按行存储,不支持块压缩,- 默认格式,数据不做压缩,磁盘开销大,加载数据的速度最高 ORCFile : 存储方式:数据按行分块,每块按照列存储 压缩快,快速列存取 效率比rcfile高,是rcfile的改良版本,使用了索引 使用ORC文件格式可以提高hive读、写和处理数据的能力 RCFile数据按行分块,每块按列存储,结合了行存储和列存储的优点 RCFile 保证同一行的数据位于同一节点,因此组重构的开销很低 RCFile 能够利用列维度的数据压缩,并且能跳过不必要的列读取 PARQUET :按列存储,相对于ORC,Parquet压缩比较低,查询效率较低 SequenceFile Hadoop API提供的一种二进制文件,以的形式序列化到文件中 存储方式:行存储 十一、介绍一些Hive调优手段 Fetch抓取 Fetch抓取是指,Hive中对某些情况的查询可以不必使用MapReduce计算。例如:SELECT * FROM employees;在这种情况下,Hive可以简单地读取employee对应的存储目录下的文件,然后输出查询结果到控制台 在hive-default.xml.template文件中hive.fetch.task.conversion默认是more,老版本hive默认是minimal,该 属性修改为more以后,在全局查找、字段查找、limit查找等都不走mapreduce 本地模式 大多数的Hadoop Job是需要Hadoop提供的完整的可扩展性来处理大数据集的。不过,有时Hive的输入 数据量是非常小的。在这种情况下,为查询触发执行任务时消耗可能会比实际job的执行时间要多的 多。对于大多数这种情况,Hive可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行 时间可以明显被缩短 用户可以通过设置hive.exec.mode.local.auto的值为true,来让Hive在适当的时候自动启动这个优化 表的优化 1)小表、大表join 将key相对分散,并且数据量小的表放在join的左边,这样可以有效减少内存溢出错误发生的几率;再进 一步,可以使用Group让小的维度表(1000条以下的记录条数)先进内存。在map端完成reduce 实际测试发现:新版的hive已经对小表JOIN大表和大表JOIN小表进行了优化。小表放在左边和右边已经 没有明显区别 2)大表Join小表 空KEY过滤 有时join超时是因为某些key对应的数据太多,而相同key对应的数据都会发送到相同的reducer上,从而 导致内存不够。此时我们应该仔细分析这些异常的key,很多情况下,这些key对应的数据是异常数据, 我们需要在SQL语句中进行过滤。例如key对应的字段为空 3)Group By 默认情况下,Map阶段同一Key数据分发给一个reduce,当一个key数据过大时就倾斜了 并不是所有的聚合操作都需要在Reduce端完成,很多聚合操作都可以先在Map端进行部分聚合,最后在 Reduce端得出最终结果 4)Count(Distinct) 去重统计 数据量小的时候无所谓,数据量大的情况下,由于COUNT DISTINCT操作需要用一个Reduce Task来完 成,这一个Reduce需要处理的数据量太大,就会导致整个Job很难完成,一般COUNT DISTINCT使用先 GROUP BY再COUNT的方式替换 5)笛卡尔积 尽量避免笛卡尔积,join的时候不加on条件,或者无效的on条件,Hive只能使用1个reducer来完成笛卡 尔积 使用分区剪裁、列剪裁 尽可能早地过滤掉尽可能多的数据量,避免大量数据流入外层SQL。 列剪裁只需要的列的数据,减少数据输入。 分区裁剪分区在hive实质上是目录,分区裁剪可以方便直接地过滤掉大部分数据。尽量使用分区过滤,少用select * 避免数据倾斜 参考数据倾斜的部分 十二、left join、right join、inner join、left semi join关联结果的差异,描述它们各自的特性。 参考答案: left join:以左表为主表,右表中有的就会关联上,右表中没有关联上的数据就用 null 补齐。 right join:以右表为主表,左表有的则关联,没有则null补齐。 left semi join:判断左表中的关联键是否在右表中存在,若存在,则返回左表的存在的数据的相关字段,若不存在,则不返回。 inner join:两个表中关联键相同的记录才会查询出来。 十三、Hive分区和分桶的区别 参考答案 1、定义上 分区 Hive的分区使用HDFS的子目录功能实现,每一个子目录包含了分区对应的列名和每一列的值。 Hive的分区方式:由于Hive实际是存储在HDFS上的抽象,Hive的一个分区名对应一个目录名,子分 区名就是子目录名,并不是一个实际字段。 在插入数据的时候指定分区,其实就是新建一个目录或者子目录,或者 在原有的目录上添加数据文件。 分桶分桶表是在表或者分区表的基础上,进一步对表进行组织,Hive使用对分桶所用的值; 进行hash,并用hash结果除以桶的个数做取余运算的方式来分桶,保证了每个桶中都有数据,但 每个桶中的数据条数不一定相等。 2、数据类型上 分桶随机分割数据库,分区是非随机分割数据库。因为分桶是按照列的哈希函数进行分割的,相对比较平均;而分区是按照列的值来进行分割的,容易造成数据倾斜。 分桶是对应不同的文件(细粒度),分区是对应不同的文件夹(粗粒度)。桶是更为细粒度的数据范围划分,分桶的比分区获得更高的查询处理效率,使取样更高效。 注意:普通表(外部表、内部表)、分区表这三个都是对应HDFS上的目录,桶表对应是目录里的文件 十四、静态分区、动态分区的区别 参考答案 静态分区是手动指定,而动态分区是通过数据来进行判断。详细来说,静态分区的列是在编译时期,通过用户传递来决定的;动态分区只有在SQL执行时才能决定。 写入的时候的区别:静态分区在插数语句的后边就要添加字段和字段值后,不需要再sql的查询语句再添加该字段;动态分区在插数语句后边添加字段后,还需要在sql的查询语句的最后,把该字段加上。 十五、Hive的union和union all的区别 参考答案 Union :对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序; Union All :对两个结果集进行并集操作,包括重复行,不进行排序。 十六、Hive中常见的数据压缩格式及它们的特点 参考答案 gzip压缩:压缩率比较高,而且压缩/解压速度也比较快;但是不支持split。当每个文件压缩之后在130M以内的(1个块大小内),都可以考虑用gzip压缩格式。 lzo压缩:压缩/解压速度也比较快,合理的压缩率;支持split,是hadoop中最流行的压缩格式。一个很大的文本文件,压缩之后还大于200M以上的可以考虑,而且单个文件越大,lzo优点越越明显。 snappy压缩:高速压缩速度和合理的压缩率;不支持split;压缩率比gzip要低。当mapreduce作业的map输出的数据比较大的时候,作为map到reduce的中间数据的压缩格式;或者作为一个mapreduce作业的输出和另外一个mapreduce作业的输入。 bzip2压缩:支持split;具有很高的压缩率,比gzip压缩率都高;压缩/解压速度慢。适合对速度要求不高,但需要较高的压缩率的时候,可以作为mapreduce作业的输出格式。
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/71447.html