hive面试题

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

external修饰的是内部表(managed table),被external修饰的为外部表(external table);
区别:
内部表数据由Hive自身管理,外部表数据由HDFS管理;
内部表数据存储的位置是hive.metastore.warehouse.dir(默认:/user/hive/warehouse

外部表数据的存储位置由自己制定(如果没有LOCATIONHive将在HDFS上的/user/hive/warehouse文件夹下以外部表的表名创建一个文件夹,并将属于这个表的数据存放在这里);
删除内部表会直接删除元数据(metadata)及存储数据;删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除;
对内部表的修改会将修改直接同步给元数据,而对外部表的表结构和分区进行修改,则需要修复(MSCK REPAIR TABLE table_name;

2.hive转换joinMR的原理?

Hive中的Join可分为Common JoinReduce阶段完成join)和Map JoinMap阶段完成join

如果不指定MapJoin或者不符合MapJoin的条件,那么Hive解析器会将Join操作转换成Common Join,即:在Reduce阶段完成join.
整个过程包含MapShuffleReduce阶段。

1: hive common join

    Map阶段

读取源表的数据,Map输出时候以 Join on 条件中的列为key,如果Join有多个关联键,则以这些关联键的组合作为key;

Map输出的 value join 之后所关心的(select或者where中需要用到的)列;同时在value中还会包含表的 Tag 信息,用于标明此value对应哪个表;

按照key进行排序

    Shuffle阶段

根据key的值进行hash,并将key/value按照hash值推送至不同的reduce中,这样确保两个表中相同的key位于同一个reduce

    Reduce阶段

     根据key的值完成join操作,期间通过Tag来识别不同表中的数据。

2: hive map join

MapJoin通常用于一个很小的表和一个大表进行 Join 的场景,具体小表有多小,由参数hive.mapjoin.smalltable.filesize来决定,该参数表示小表的总大小,默认值为25000000字节,即25M

0.7版本之后,默认自动会转换Map Join,由参数 hive.auto.convert.join 来控制,默认为true.

3.Hive表关联查询,如何解决数据倾斜的原因以及解决办法?

倾斜原因:

map输出数据按key Hash的分配到reduce中,由于key分布不均匀、业务数据本身的特性、建表时考虑不周等原因造成的reduce 上的数据量差异过大。

解决方案:

1)参数调节:

hive.map.aggr = true

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中),最后完成最终的聚合操作。

2SQL 语句调节:

1)选用join key分布最均匀的表作为驱动表。做好列裁剪和filter操作,以达到两表做join 的时候,数据量相对变小的效果。

2)大小表Join

使用map join让小的维度表(1000 条以下的记录条数)先进内存。在map端完成reduce.

3)大表Join大表:

把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null 值关联不上,处理后并不影响最终结果。

4)count distinct大量相同特殊值:

count distinct 时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1。如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union

5.Hive的两张表关联,使用MapReduce怎么实现?

情况一

如果其中一张表为小表,可以直接在mapjoin的方式进行聚合

情况二

如果两张表都是大表,可以采用联合key的方式进行聚合。联合key的第一个部分join on的部分为公共字段,第二部分添加一个flag,就是一个标记,用来区分两张表,0代表着表A1代表着表B。用来让Reduce端区分两张表的信息。在Mapper进行表的处理,join on公共字段相同的数据划分到同一个分区中,进而传输到一个reduce中,然后进行聚合。

 6.请说明hiveSort ByOrder ByCluster ByDistrbute By各代表什么意思?

1.order by 会对输入做全局排序,为保证全局的排序,因此只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。

2. sort by不是全局排序,其在数据进入reducer前完成排序。因此,如果用sort by进行排序,则sort by只保证每个reducer的输出有序,不保证全局有序。

3. distribute by(字段)根据指定的字段将数据分到不同的reducer,且分发算法是hash散列,常用sort by结合使用,Hive要求distribute by语句要写在sort by语句之前。

4. cluster by(字段) 除了具有distribute by的功能(既可以把数据分到不同的reduce)外,还会对该字段进行排序.但是排序只能是倒序排序,不能指定排序规则为asc或者desc

因此:

当数据量规模较大时,不使用order by,使用用distribute by + sort by

如果distribute by sort by字段是同一个时,此时,cluster by = distribute by + sort by

7.Hive有哪些方式保存元数据,各有哪些特点?

1、内嵌模式:将元数据保存在本地内嵌的derby数据库中,内嵌的derby数据库每次只能访问一个数据文件,也就意味着它不支持多会话连接。

2. 本地模式:将元数据保存在本地独立的数据库中(一般是mysql),这可以支持多会话连接。

3. 远程模式:把元数据保存在远程独立的mysql数据库中,避免每个客户端都去安装mysql数据库。

三种配置方式区别

    内嵌模式使用的是内嵌的Derby数据库来存储元数据,也不需要额外起Metastore服务。这个是默认的,配置简单,但是一次只能一个客户端连接,适用于用来实验,不适用于生产环境。

    本地元存储和远程元存储都采用外部数据库来存储元数据,目前支持的数据库有:MySQLPostgresOracleMS SQL Server.在这里我们使用MySQL

    本地元存储和远程元存储的区别是:本地元存储不需要单独起metastore服务,用的是跟hive在同一个进程里的metastore服务。远程元存储需要单独起metastore服务,然后每个客户端都在配置文件里配置连接到该metastore服务。远程元存储的metastore服务和hive运行在不同的进程

  1. Hive的函数:UDFUDAFUDTF的区别

1UDF:一进一出

实现方法:

1. 继承UDF

2. 重写evaluate方法

3. 将该java文件编译成jar

4. 在终端输入如下命令:

hive> add jar test.jar;

hive> create temporary function function_name as 'com.hrj.hive.udf.UDFClass';

hive> select function_name(t.col1) from table t;

hive> drop temporary function function_name;

2UDAF:多进一出

实现方法:

1,用户的UDAF必须继承了org.apache.hadoop.hive.ql.exec.UDAF

2,用户的UDAF必须包含至少一个实现了org.apache.hadoop.hive.ql.exec的静态类,诸如实现了 UDAFEvaluator

3,一个计算函数必须实现的5个方法的具体含义如下:

init():主要是负责初始化计算函数并且重设其内部状态,一般就是重设其内部字段。一般在静态类中定义一个内部字段来存放最终的结果。

iterate():每一次对一个新值进行聚集计算时候都会调用该方法,计算函数会根据聚集计算结果更新内部状态。当输 入值合法或者正确计算了,则       就返回true

terminatePartial()Hive需要部分聚集结果的时候会调用该方法,必须要返回一个封装了聚集计算当前状态的对象。

merge()Hive进行合并一个部分聚集和另一个部分聚集的时候会调用该方法。

terminate()Hive最终聚集结果的时候就会调用该方法。计算函数需要把状态作为一个值返回给用户。

4.部分聚集结果的数据类型和最终结果的数据类型可以不同。

3UDTF:一进多出

实现方法:

1. 继承org.apache.hadoop.hive.ql.udf.generic.GenericUDTF

2.initialize()UDTF首先会调用initialize方法,此方法返回UDTF的返回行的信息(返回个数,类型)

3.process:初始化完成后,会调用process方法,真正的处理过程在process函数中,在process中,每一次forward() 调用产生一行;如果产生多列      可以将多个列的值放在一个数组中,然后将该数组传入到forward()函数

4.最后close()方法调用,对需要清理的方法进行清理

 8.说说对Hive桶表的理解

分桶: MapReduce中分区是一个概念! 是把数据分散到多个文件中!

分桶本质上也是为了分散数据!在分桶后,可以结合hive提供的抽样查询,只查询指定桶的数据

桶表的创建:create table btable1 (id int) clustered by (id) into 4 buckets;

创建只有一个字段(id)的桶表,按照id分桶,分为4bucket,buchet的数量等于实际数据插入中reduce的数量

 9.说一下Hive并行执行

Hive会将一个查询转化成一个或者多个阶段。

这样的阶段可以是MapReduce阶段、抽样阶段、合并阶段、limit阶段。或者Hive执行过程中可能需要的其他阶段。默认情况下,Hive一次只会执行一个阶段。

不过,某个特定的job可能包含众多的阶段,而这些阶段可能并非完全互相依赖的,也就是说有些阶段是可以并行执行的,这样可能使得整个job的执行时间缩短。

不过,如果有更多的阶段可以并行执行,那么job可能就越快完成。

通过设置参数hive.exec.parallel值为true,就可以开启并发执行。

不过,在共享集群中,需要注意下,如果job中并行阶段增多,那么集群利用率就会增加。

   1set hive.exec.parallel=true;              //打开任务并行执行

   2set hive.exec.parallel.thread.number=16;  //同一个sql允许最大并行度,默认为8

当然,得是在系统资源比较空闲的时候才有优势,否则,没资源,并行也起不来。

10.Hive 中的压缩格式TextFileSequenceFileRCfile ORCfile各有什么区别

TextFile: 默认格式,数据不做压缩,磁盘开销大,数据解析开销大。可结合GzipBzip2使用,但使用Gzip这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。

SequenceFile: SequenceFileHadoop API 提供的一种二进制文件,它将数据以<key,value>的形式序列化到文件中。这种二进制文件内部使用Hadoop 的标准的Writable 接口实现序列化和反序列化。它与Hadoop API中的MapFile 是互相兼容的。Hive 中的SequenceFile 继承自Hadoop API SequenceFile,不过它的key为空,使用value 存放实际的值, 这样是为了避免MR 在运行map 阶段的排序过程。

RCFile: RCFileHive推出的一种专门面向列的数据格式。 它遵循先按列划分,再垂直划分的设计理念。当查询过程中,针对它并不关心的列时,它会在IO上跳过这些列。需要说明的是,RCFilemap阶段从 远端拷贝仍然是拷贝整个数据块,并且拷贝到本地目录后RCFile并不是真正直接跳过不需要的列,并跳到需要读取的列, 而是通过扫描每一个row group的头部定义来实现的,但是在整个HDFS Block 级别的头部并没有定义每个列从哪个row group起始到哪个row group结束。所以在读取所有列的情况下,RCFile的性能反而没有SequenceFile高。

ORCfile: ORC是列式存储,有多种文件压缩方式,并且有着很高的压缩比。文件是可切分(Split)的。因此,在Hive中使用ORC作为表的文件存储格式,不仅节省HDFS存储资源,查询任务的输入数据量减少,使用的MapTask也就减少了。提供了多种索引,row group indexbloom filter indexORC可以支持复杂的数据结构(比如Map等)

原文地址:https://www.cnblogs.com/comw/p/14243151.html