Hive面试题

Hive将SQL转为MapReduce的流程

  1. Antlr定义SQL的语法规则, 完成SQL词法、语法解析,将SQL转换为抽象语法树AST Tree
  2. 遍历AST Tree,抽象出基本组成单元QueryBlock(查询块)
  3. 遍历QueryBlock,翻译为执行操作树OperatorTree
  4. 逻辑层优化器进行OperatorTree优化,合并不必要的ReduceSinkOperator,减少shuffle数据量
  5. 遍历OperatorTree,翻译为MapReduce任务
  6. 物理层优化器进行MapReduce任务的优化,生成最终的执行计算。

数据倾斜

表现

数据倾斜表现在map/reduce执行时,reduce节点大部分执行完成,只有一个或几个reduce节点运行很慢,导致整个程序的处理时间很长。

原因

数据倾斜可能发生在group和join阶段

  • key分布不均匀,某个/些key的数据比其他key多很多,导致这个key所在节点的数据量很大。
  • 业务数据本身的特性
  • 建表考虑不周全
  • HQL语句本身存在数据倾斜
解决方式
大表和小表关联时
  • 将数据分布均匀的小表放在前面,可以触发reduce端更少的操作次数

  • 使用map join将小表缓存到内存中,在map端完成join的过程。

    开启map-side-join的属性:set hive.auto.convert.join=true

    设置优化小表的大小:set hive.mapjoin.smalltable.filesize=25000000

大表和大表关联时
  • 空值或0比较多时,可以对异常值赋一个随机值来分散key,均匀分配给多个reduce执行

  • 通过配置参数,让hive自己进行优化。

    set hive.exec.reducers.bytes.per.reducer=1000000000,也就是每个节点的reduce默认是处理1G的数据。

    set hive.optimize.skewjoin=true 开启join数据倾斜的优化。

    set hive.skewjoin.key=skew_key_threshold 控制数据倾斜的阈值

  • 对于特殊明确的几个key导致的倾斜,可以单独提取出来进行关联,将结果进行union all合并

group数据倾斜时
  • 通过配置参数,让hive自己进行优化。

    set hive.map.aggr=true,代表在map端进行聚合,相当于combiner

    set hive.groupby.skewindata=true,表示有数据倾斜时进行负载均衡,生成的查询计划会有两个MR job。第一个MR job中,map的输出结果随机分布到reduce中,每个reduce做部分聚合操作,并输出结果。这样做的结果是相同的group key可能分发到不同的reduce中,从而达到负载均衡的作用。第二个MR Job在根据预处理的数据结果按照group by key分布到reduce中,最后完成最终的聚合操作。

    set hive.groupby.mapaggr.checkinterval = 100000 (默认)执行聚合的条数

通用方式
  • 增大reduce的数量

    set mapred.reduce.tasks=100,指定reduce的个数

    如果不指定reduce的数量,默认是通过hive.exec.reducers.bytes.per.reducer来计算reduce 的数量。

Hive的优化?

本地模式

当hive输入数据量很小时,触发job执行时间比数据处理时间还长

set hive.exec.mode.local.auto=true 启动本地模式优化

并行执行

并行执行job的多个阶段,提高集群的利用率

set hive.exec.parallel=true

严格模式

通过set hive.mapred.mode=strict开启严格模式,有以下3个约束:

  1. 对于分区表,where中必须有分区字段过滤条件
  2. 对于order by查询,必须有limit
  3. 限制笛卡尔积
小文件处理

控制小文件的生成:减少reduce的数量

对已存在小文件的处理方案:

  1. 使用Hadoop Achieve对小文件进行归档
  2. 重建表,建表时减少reduce的数量
  3. 调节mapper/reducer数量
调整mapper和reducer的数量

hive会将查询分为一个或多个MapReduce任务达到并行的目的。

适当的调整mapper和reducer数量,可以加快运行的速度

调整mapper数量

https://www.cnblogs.com/chengdu-jackwu/p/10170895.html

mapper数量的决定因素有:input的文件总个数、input的文件大小、集群设置的文件块大小

可以通过以下参数调整:

set mapred.max.split.size=100000000; – 决定每个map处理的最大的文件大小,单位为B

set mapred.min.split.size.per.node=100000000; – 节点中可以处理的最小的文件大小

set mapred.min.split.size.per.rack=100000000; – 机架中可以处理的最小的文件大小

set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;—实现map中的数据合并

调整reducer数量

reducer数量是按照输入的数据量来确定的。

参数hive.exec.reducers.bytes.per.reducer的默认值是1GB,表示每个reduce处理1GB的数据。

hive默认的reducer数量是3,可以通过设置mapred.reduce.tasks的值来修改。

为了控制资源的利用情况,华兴hive.exec.reducers.max也必须设置,限制最大reducer数量

JVM重用

对于task数量多的job,可以开启JVM重用,使得JVM实例在同一个job中重复使用N次。

N的值通过mapred.job.reuse.jvm.num.tasks设置

推测执行

触发执行一些重复的任务。解决部分task由于机器资源紧张而久久不能完成的问题。

set hive.mapred.reduce.tasks.speculative.execution=true开启推测执行

几种排序的区别:

order by 对输入做全局排序,因此只有一个reduce,输入规模过大时,需要比较长的计算时间

sort by 不是全局排序,在数据进入reduce前完成排序,保证每个reduce输出有序,不保证全局有序

distributed by 根据制定的内容将数据分到同一个reduce中

cluster by 除了具有 distribute的功能外,还会对该字段进行排序(分桶)

Hive的特点

  • 将结构化数据文件映射为数据库表,提供完整的sql查询能力
  • 本质是在MapReduce上加了一层sql的壳,是一种离线数据分析工具
  • 通过制造冗余来提高查询能力
  • 不支持强事务

Hive的一些概念

数据库:底层是HDFS中国一个库名.db的文件夹

表:库名文件夹下以表名为名字的子文件

行数据:表名文件夹下的文件

HQL:会转换成底层的mapreduce执行

default库:对应hdfs中的/user/hive/warehouse

内部表外部表

未被external修饰的表是内部表(managed table),被external修饰的是外部表(external table)

内部表的数据是由Hive自身管理的,外部表的数据是由HDFS管理的。

删除内部表会删除元数据和存储的数据;删除外部表只删除元数据不删除存储的数据。内部表的数据在hive中删除,在HDFS中也就删除了;但是外部表的数据,在Hive中删除,HDFS中还是存在的。

insert into和insert overwrite

insert into 与 insert overwrite 都可以向hive表中插入数据,但是insert into直接追加到表中数据的尾部,而insert overwrite会重写数据,先进行删除,再写入。

如果存在分区的情况,insert overwrite会只重写当前分区数据。

Hive元数据库中的表

DBS存储了库相关信息,库编号、库名称、库所有者、库对应在HDFS中的位置

TBLS存储了表相关信息,表的编号、所属库编号、表所有者、表名称、表类型等

COLUMN_V2存储了对应列的信息,列编号、列名称、列类型、列位置等

SDS存储了表在HDFS中存储的吻戏信息,表的编号和存储位置

分区和分桶的区别

分区

是指按照数据表的某列或某些列分为多个区,区从形式上可以理解为文件夹,比如我们要收集某个大型网站的日志数据,一个网站每天的日志数据存在同一张表上,由于每天会生成大量的日志,导致数据表的内容巨大,在查询时进行全表扫描耗费的资源非常多。

这个情况下,我们可以按照日期对数据表进行分区,不同日期的数据存放在不同的分区,在查询时只要指定分区字段的值就可以直接从该分区查找。

分桶

分桶是相对分区进行更细粒度的划分。

分桶将整个数据内容安装某列属性值得hash值进行区分,如要按照name属性分为3个桶,就是对name属性值的hash值对3取摸,按照取模结果对数据分桶。

如取模结果为0的数据记录存放到一个文件,取模为1的数据存放到一个文件,取模为2的数据存放到一个文件。

left join和left semi join区别

left join就是left outer join,返回左右表符合on条件的数据。如果右表和左表有多条数据匹配,就会返回多条数据。

left semi join左半连接,返回符合on条件的左表的数据。如果右表和左表有多条数据匹配,只会返回一次左表的数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值