hive⾯试题总结(⼤数据⾯试)
Hive概述
Hive是基于Hadoop的⼀个数据仓库⼯具,可以将结构化的数据⽂件映射成为⼀张数据库表,并提供类SQL的查询功能。可以将sql语句转化为MapReduce任务进⾏运⾏。Hive提供了⼀系列的⼯具,可以⽤来进⾏数据提取转化加载(ETL),这是⼀种可以存储、查询和分析存储在 Hadoop 中的⼤规模数据的机制。
1、Hive ⾃定义函数函数
UDF ⼀进⼀出 处理原⽂件内容某些字段包含 [] “”
UDAF 多进⼀出 sum() avg() max() min()
UDTF ⼀进多出 ip -> 国家 省 市
2、Hive4种排序
order by //可以指定desc 降序 asc 升序 order
by会对输⼊做全局排序,因此只有⼀个Reducer(多个Reducer⽆法保证全局有序),然⽽只有⼀个Reducer,会导致当输⼊规模较⼤时,消耗较长的计算时间。
sort by 【对分区内的数据进⾏排序】 sort by不是全局排序,其在数据进⼊reducer前完成排序,因此,如果⽤sort by进⾏排序,并且设置duce.tasks>1,则sort by只会保证每个reducer的输出有序,并不保证全局有序。sort by不同于order by,它不受de属性的影响,sort by的数据只能保证在同⼀个reduce中的数据可以按指定字段排序。使⽤sort by你可以指定执⾏的reduce个数(通过duce.tasks=n来指定),对输出的数据再执⾏归并排序,即可得到全部结果。
distribute by 【对map输出进⾏分区】
distribute by是控制在map端如何拆分数据给reduce端的。hive会根据distribute by后⾯列,对应reduce的个数进⾏分发,默认是采⽤hash算法。sort by为每个reduce产⽣⼀个排序⽂件。在有些情况下,你需要控制某个特定⾏应该到哪个reducer,这通常是为了进⾏后续的聚集操作。distribute by刚好可以做这件事。因此,distribute by经常和sort by配合使⽤。
cluster by
cluster by除了具有distribute by的功能外还兼具sort by的功能。当distribute by和sort by 是同⼀个字段的时候可以使⽤cluster by替代。但是排序只能是倒叙排序,不能指定排序规则为ASC或者DESC。
3、三种分组的区别
row_number:不管col2字段的值是否相等,⾏号⼀直递增,⽐如:有两条记录的值相等,但⼀个是第⼀,⼀个是第⼆
rank:上下两条记录的col2相等时,记录的⾏号是⼀样的,但下⼀个col2值的⾏号递增N(N是重复的次数),⽐如:有两条并列第⼀,下⼀个是第三,没有第⼆
dense_rank:上下两条记录的col2相等时,下⼀个col2值的⾏号递增1,⽐如:有两条并列第⼀,下⼀个是第⼆
4、Hive优化
1.fetch task任务不⾛MapReduce,可以在hive配置⽂件中设置最⼤化和最⼩化fetch task任务;通常在使⽤hiveserver2时调整为more;
2.strict mode:严格模式设置,严格模式下将会限制⼀些查询操作
a:当表为分区表时,where字句后没有分区字段和限制时,不允许执⾏。
多表查询sql语句面试题b:当使⽤order by语句时,必须使⽤limit字段,因为order by 只会产⽣⼀个reduce任务。
c:限制笛卡尔积的查询。sql语句不加where不会执⾏
3.优化sql语句,如先过滤再join,先分组再做distinct;
4.MapReduce过程的map、shuffle、reduce端的snappy压缩
需要先替换hadoop的native本地包开启压缩
在l⽂件设置启⽤压缩及压缩编码
在执⾏SQL执⾏时设置启⽤压缩和指定压缩编码
set mapreduce.output.fileoutputformatpress=true;
set mapreduce.dec=org apache.hadoop.iopress.SnappyCodec;
5.⼤表拆分成⼦表,提取中间结果集,减少每次加载数据
多维度分析,多个分析模块
每个分析模块涉及字段不⼀样,⽽且并不是表的全部字段
6.分区表及外部表
设计⼆级分区表(⼀级字段为天,⼆级字段设置⼩时)
创建的的是外部表,创建表时直接指定数据所在⽬录即可,不⽤再⽤load加载数据
7.设置map和reduce个数:默认情况下⼀个块对应⼀个map任务,map数据我们⼀般不去调整,reduce个数根据reduce处理的数据量⼤⼩进⾏适当调整体现“分⽽治之”的思想
8.JVM重⽤:⼀个job可能有多个map reduce任务,每个任务会开启⼀个JVM虚拟机,默认情况下⼀个任务对应⼀个JVM,任务运⾏完JVM即销毁,我们可以设置JVM重⽤参数,⼀般不超过5个,这样⼀个JVM内可以连续运⾏多个任务
JVM重⽤是Hadoop调优参数的内容,对Hive的性能具有⾮常⼤的影响,特别是对于很难避免⼩⽂件的场景或者task特别多的场景,这类场景⼤多数执⾏时间都很短。hadoop默认配置是使⽤派⽣JVM来执⾏map和reduce任务的,这是jvm的启动过程可能会造成相当⼤的开销,尤其是执⾏的job包含有成千上万个task任务的情况。
JVM重⽤可以使得JVM实例在同⼀个JOB中重新使⽤N次,N的值可以在Hadoop的l⽂件中进⾏设置(建议参考5~10)
9.推测执⾏:例如⼀个Job应⽤有10个MapReduce任务(map 及reduce),其中9个任务已经完成,那么application Master会在另外启动⼀个相同的任务来运⾏未完成的那个,最后哪个先运⾏完成就把另⼀个kill掉
启⽤speculative最⼤的好处是,⼀个map执⾏的时候,系统会在其他空闲的服务器上启动相同的map来同时运⾏,哪个运⾏的快就使⽤哪个的结果,另⼀个运⾏慢的在有了结果之后就会被kill。
5、数据倾斜
原因
key分布不均匀
业务数据本⾝的特性
SQL语句造成数据倾斜
对于普通的join操作,会在map端根据key的hash值,shuffle到某⼀个reduce上去,在reduce端做join连接操作,内存中缓存join左边的表,遍历右边的表,依次做join操作。所以在做join操作时候,将数据量多的表放在join的右边。
当数据量⽐较⼤,并且key分布不均匀,⼤量的key都shuffle到⼀个reduce上了,就出现了数据的倾斜。
常见的数据倾斜出现在group by和join…on…语句中。
join(数据倾斜)
在进⾏两个表join的过程中,由于hive都是从左向右执⾏,要注意讲⼩表在前,⼤表在后(⼩表会先进⾏缓存)。
map/reduce程序执⾏时,reduce节点⼤部分执⾏完毕,但是有⼀个或者⼏个reduce节点运⾏很慢,导致整个程序的处理时间很长,这是因为某⼀个key的条数⽐其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量⽐其他节点就⼤很多,从⽽导致某⼏个节点迟迟运⾏不完,此称之为数据倾斜。hive在跑数据时经常会出现数据倾斜的情况,使的作业经常reduce完成在99%后⼀直卡住,最后的1%花了⼏个⼩时都没跑完,这种情况就很可能是数据倾斜的原因,
控制⽣成两个MR Job,第⼀个MR Job Map的输出结果随机分配到reduce中减少某些key值条数过多某些key条数过⼩造成的数据倾斜问题。
在第⼀个 MapReduce 中,map 的输出结果集合会随机分布到 reduce 中, 每个reduce 做部分聚合操作,并输出结果。这样处理的结果是,相同的 Group By Key 有可能分发到不同的reduce中,从⽽达到负载均衡的⽬的;
第⼆个 MapReduce 任务再根据预处理的数据结果按照 Group By Key 分布到 reduce 中(这个过程可以保证相同的 Group By Key 分布到同⼀个 reduce 中),最后完成最终的聚合操作。
hive.optimize.skewjoinpiletime=true; 如果是join过程出现倾斜应该设置为true
此时会将join语句转化为两个mapreduce任务,第⼀个会给jion字段加随机散列
set hive.skewjoin.key=100000; 这个是join的键对应的记录条数超过这个值则会进⾏优化。
6、Hive中追加导⼊数据的4种⽅式是什么?请写出简要语法
从本地导⼊: load data local inpath ‘/’ (overwrite)into table student;
从Hdfs导⼊: load data inpath ‘/user/hive/’ (overwrite)into table student;
查询导⼊: create table student1 as select * from student;(也可以具体查询某项数据)
查询结果导⼊:insert (overwrite)into table staff select * from track_log;
7、Hive导出数据有⼏种⽅式?如何导出数据
1、⽤insert overwrite导出⽅式
导出到本地: insert overwrite local directory ‘/home/robot/1/2’ rom format
delimited fields terminated by ‘\t’ select * from staff;(递归创建⽬录)
导出到HDFS insert overwrite directory ‘/user/hive/1/2’ rom format
delimited fields terminated by ‘\t’ select * from staff;
2、Bash shell覆盖追加导出
例如:$ bin/hive -e “select * from staff;” > /home/z/backup.log
3、Sqoop把hive数据导出到外部
8、合并⼩⽂件
9、⾃定义map/reduce数⽬
减少map数⽬:
  set mapred.max.split.size
  set mapred.min.split.size
  set mapred.min.split.de
  set mapred.min.split.size.per.rack
  set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
增加map数⽬:
当input的⽂件都很⼤,任务逻辑复杂,map执⾏⾮常慢的时候,可以考虑增加Map数,来使得每个map处理的数据量减少,从⽽提⾼任务的执⾏效率。
假设有这样⼀个任务:
select data_desc, count(1), count(distinct id),sum(case when …),sum(case when …),sum(…) from a group by data_desc
如果表a只有⼀个⽂件,⼤⼩为120M,但包含⼏千万的记录,如果⽤1个map去完成这个任务,肯定是⽐较耗时的,这种情况下,我们要考虑将这⼀个⽂件合理的拆分成多个,这样就可以⽤多个map任务去完成。
  duce.tasks=10;
  create table a_1 as select * from a distribute by rand(123);
这样会将a表的记录,随机的分散到包含10个⽂件的a_1表中,再⽤a_1代替上⾯sql中的a表,则会⽤10个map任务去完成。每个map任务处理⼤于12M(⼏百万记录)的数据,效率肯定会好很多。
reduce数⽬设置:
参数1:ducers.ducer=1G:每个reduce任务处理的数据量
参数2:ducers.max=999(0.95TaskTracker数):每个任务最⼤的reduce数⽬
reducer数=min(参数2,总输⼊数据量/参数1)
duce.tasks:每个任务默认的reduce数⽬。典型为0.99reduce槽数,hive将其设置为-1,⾃动确定reduce数⽬。10、使⽤索引:
hive.optimize.index.filter:⾃动使⽤索引
hive.upby:使⽤聚合索引优化GROUP BY操作
11、分区和分桶
分区
是指按照数据表的某列或某些列分为多个区,区从形式上可以理解为⽂件夹,⽐如我们要收集某个⼤型⽹站的⽇志数据,⼀个⽹站每天的⽇志数据存在同⼀张表上,由于每天会⽣成⼤量的⽇志,导致数据表的内容巨⼤,在查询时进⾏全表扫描耗费的资源⾮常多。
那其实这个情况下,我们可以按照⽇期对数据表进⾏分区,不同⽇期的数据存放在不同的分区,在查询时只要指定分区字段的值就可以直接从该分区查
分桶
分桶是相对分区进⾏更细粒度的划分。
分桶将整个数据内容安装某列属性值得hash值进⾏区分,如要按照name属性分为3个桶,就是对name属性值的hash值对3取摸,按照取模结果对数据分桶。
如取模结果为0的数据记录存放到⼀个⽂件,取模为1的数据存放到⼀个⽂件,取模为2的数据存放到⼀个⽂件
12、Hive 中的压缩格式 RCFile、 TextFile、 SequenceFile 各有什么区别?
TextFile:默认格式,数据不做压缩,磁盘开销⼤,数据解析开销⼤。
SequenceFile:Hadoop API提供的⼀种⼆进制⽂件⽀持,使⽤⽅便,可分割,可压缩,⽀持三种压缩,NONE,RECORD,BLOCK。
RCFILE:是⼀种⾏列存储相结合的⽅式。⾸先,将数据按⾏分块,保证同⼀个record在同⼀个块上,避免读⼀个记录读取多个block。其次,块数据列式存储,有利于数据压缩和快速的列存取。数据加载的时候性能消耗⼤,但具有较好的压缩⽐和查询响应。
企业中hive常⽤的数据存储格式是ORC格式,数据压缩格式是snappy

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。