大数据面试之hive重点(二)

25 篇文章 0 订阅
6 篇文章 0 订阅

大数据面试之hive重点(二)
Hive SQL转化为MR的过程?
可回答:1)Hive SQL的解析过程;2)Hive SQL的底层实现
问过的一些公司:阿里,头条,小米,滴滴,美团x2,网易,快手58,好未来
参考答案:
我们先来看下MapReduce框架实现SQL基本操作的原理 :
1、Join的实现原理

1 select u.name, o.orderid from order o join user u on o.uid = u.uid; 2
在map的输出value中为不同表的数据打上tag标记,在reduce阶段根据tag判断数据来源。MapReduce的 过程如下(这里只是说明最基本的Join的实现,还有其他的实现方式)在这里插入图片描述

2、Group By的实现原理

1 select rank, isonline, count(*) from city group by rank, isonline; 2
将GroupBy的字段组合为map的输出key值,利用MapReduce的排序,在reduce阶段保存LastKey区分不同 的key。MapReduce的过程如下(当然这里只是说明Reduce端的非Hash聚合过程)
在这里插入图片描述
3、Distinct的实现原理

1 select dealid, count(distinct uid) num from order group by dealid; 2
当只有一个distinct字段时,如果不考虑Map阶段的Hash GroupBy,只需要将GroupBy字段和Distinct字段组合为map输出key,利用mapreduce的排序,同时将GroupBy字段作 为reduce的key,在reduce阶段保存LastKey即可完成去重.
在这里插入图片描述
如果有多个distinct字段呢,如下面的SQL

1 select dealid, count(distinct uid), count(distinct date) from order group by dealid;
2
实现方式有两种:

  1. 如果仍然按照上面一个distinct字段的方法,即下图这种实现方式,无法跟据uid和date分别排序,也 就无法通过LastKey去重,仍然需要在reduce阶段在内存中通过Hash去重
    在这里插入图片描述
  2. 第二种实现方式,可以对所有的distinct字段编号,每行数据生成n行数据,那么相同字段就会分别排 序,这时只需要在reduce阶段记录LastKey即可去重。
    这种实现方式很好的利用了MapReduce的排序,节省了reduce阶段去重的内存消耗,但是缺点是增加了
    shuffle的数据量。
    需要注意的是,在生成reduce value时,除第一个distinct字段所在行需要保留value值,其余distinct数据行value字段均可为空。
    在这里插入图片描述
    SQL转化为MapReduce的过程
    通过前面的部分了解了MapReduce实现SQL基本操作之后,我们来看看Hive是如何将SQL转化为
    MapReduce任务的,整个编译过程分为六个阶段:
    Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree
    遍历AST Tree,抽象出查询的基本组成单元QueryBlock
    遍历QueryBlock,翻译为执行操作树OperatorTree
    逻辑层优化器进行OperatorTree变换,合并不必要的ReduceSinkOperator,减少shuffle数据量 遍历OperatorTree,翻译为MapReduce任务
    物理层优化器进行MapReduce任务的变换,生成最终的执行计划
    详细部分篇幅过大,可在网上查看

Hive SQL优化处理
问过的一些公司:携程,快手(2021.09) 参考答案:
优化的根本思想
尽早尽量过滤数据,减少每个阶段的数据量减少job数
解决数据倾斜问题
1、Map Join
如果不指定 MapJoin 或者不符合 MapJoin 的条件,那么 Hive 解析器会将 Join 操作转换 成 Common Join,即:在 Reduce 阶段完成 join。容易发生数据倾斜。可以用MapJoin把小 表全部加载到内存在 map 端进行 join,避免 reducer 处理。
2、行列过滤
列处理:在 SELECT 中,只拿需要的列,如果有,尽量使用分区过滤,少用 SELECT *。
行处理:在分区剪裁中,当使用外关联时,如果将副表的过滤条件写在 Where 后面,那 么就会先全表关联,之后再过滤。
3、多采用分桶技术
4、结合实际环境合理设置 Map 数
通常情况下,作业会通过 input的目录产生一个或者多个map任务。 主要的决定因素有:input的文件总个数,input的文件大小,集群设置的文件块大小;
map数不是越多越好;如果一个任务有很多小文件(远远小于块大小 128m),则每个小文件 也会被当做一个块,用一个 map 任务来完成,而一个 map 任务启动和初始化的时间远远大 于逻辑处理的时间, 就会造成很大的资源浪费。而且,同时可执行的 map 数是受限的。解决这个问题需要减少map数。
并不是每个map处理接近128m的文件块就是完美的;比如有一个 127m 的文件,正常会用一个 map 去完成,但这个文件只 有一个或者两个小字段,却有几千万的记录,如果 map 处理的逻辑比较复杂,用一个 map 任务去做,肯定也比较耗时。解决这个问题需要增加map数。
5、 合并大量小文件
在Map执行前合并小文件,可以减少Map数:CombineHiveInputFormat 具有对小文件进行合并的功能
(系统默认的格式)。HiveInputFormat 没有对小文件合并功能。
6、设置合理的Reduce数Reduce 个数也并不是越多越好
过多的启动和初始化Reduce 也会消耗时间和资源;
有多少个Reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为 下一个任务的输入,则也会出现小文件过多的问题;
在设置Reduce个数的时候也需要考虑这两个原则:处理大数据量利用合适的Reduce 数;使单个
Reduce 任务处理数据量大小要合适。
7、输出合并小文件常用参数

  1. SET hive.merge.mapfiles = true; – 默认 true,在 map-only 任务结束时合并小文件

  2. SET hive.merge.mapredfiles = true; – 默认 false,在 map-reduce 任务结束时合并小文件

  3. SET hive.merge.size.per.task = 268435456; – 默认 256M

  4. SET hive.merge.smallfiles.avgsize = 16777216; – 当输出文件的平均大小小于 16m 该值时, 启动一个独立的 map-reduce 任务进行文件 merge
    5
    8、开启 map 端 combiner(不影响最终业务逻辑)

  5. 开启命令

  6. set hive.map.aggr=true; 3
    9、中间结果压缩
    设置 map 端输出、中间结果压缩。(不完全是解决数据倾斜的问题,但是减少了 IO 读写和网络传输, 能提高很多效率)

Hive的存储引擎和计算引擎
可回答:1)Hive的存储和计算;2)Hive的底层引擎模式? 问过的一些公司:字节,快手,顺丰,恒生(2021.09)
参考答案:
1、计算引擎
目前Hive支持MapReduce、Tez和Spark三种计算引擎。
在低版本(Hive 1.1之前)中,Hive支持MapReduce、Tez两种计算引擎。

在高版本(Hive 1.1之后)中,Hive支持MapReduce、Tez和Spark三种就算引擎。配置命令如下:

  1. 配置mapreduce计算引擎

  2. set hive.execution.engine=mr;
  3. 配置spark计算引擎

  4. set hive.execution.engine=spark;
  5. 配置tez 计算引擎

  6. set hive.execution.engine=tez; 7
    注意版本问题
    MapReduce计算引擎:
    Map在读取数据时,先将数据拆分成若干数据,并读取到Map方法中被处理。数据在输出的时候,被分 成若干分区并写入内存缓存(buffer)中,内存缓存被数据填充到一定程度会溢出到磁盘并排序,当Map 执行完后会将一个机器上输出的临时文件进行归并存入到HDFS中。
    当Reduce启动时,会启动一个线程去读取Map输出的数据,并写入到启动Reduce机器的内存中,在数据 溢出到磁盘时会对数据进行再次排序。当读取数据完成后会将临时文件进行合并,作为Reduce函数的数 据源。
    Tez计算引擎:
    Apache Tez是进行大规模数据处理且支持DAG作业的计算框架,它直接源于MapReduce框架,除了能够支持MapReduce特性,还支持新的作业形式,并允许不同类型的作业能够在一个集群中运行。
    Tez将原有的Map和Reduce两个操作简化为一个概念——Vertex,并将原有的计算处理节点拆分成多个组 成部分:Vertex Input、Vertex Output、Sorting、Shuffling和Merging。计算节点之间的数据通信被统称为Edge,这些分解后的元操作可以任意灵活组合,产生新的操作,这些操作经过一些控制程序组装后,可 形成一个大的DAG作业。
    通过允许Apache Hive运行复杂的DAG任务,Tez可以用来处理数据,之前需要多个MR jobs,现在一个Tez
    任务中。
    在这里插入图片描述
    Spark计算引擎:
    Apache Spark是专为大规模数据处理而设计的快速、通用支持DAG(有向无环图)作业的计算引擎,类似于Hadoop MapReduce的通用并行框架,可用来构建大型的、低延迟的数据分析应用程序。
    Tez和MapReduce作业的比较
    Tez绕过了MapReduce很多不必要的中间的数据存储和读取的过程,直接在一个作业中表达了MapReduce
    需要多个作业共同协作才能完成的事情。
    Tez和MapReduce一样都运行使用YARN作为资源调度和管理。但与MapReduce on YARN不同,Tez on YARN并不是将作业提交到ResourceManager,而是提交到AMPoolServer的服务上,AMPoolServer存放着 若干已经预先启动ApplicationMaster的服务。
    当用户提交一个作业上来后,AMPoolServer从中选择一个ApplicationMaster用于管理用户提交上来的作 业,这样既可以节省ResourceManager创建ApplicationMaster的时间,而又能够重用每个ApplicationMaster的资源,节省了资源释放和创建时间。
    Tez相比于MapReduce有几点重大改进:
    当查询需要有多个reduce逻辑时,Hive的MapReduce引擎会将计划分解,每个Redcue提交一个MR作业。 这个链中的所有MR作业都需要逐个调度,每个作业都必须从HDFS中重新读取上一个作业的输出并重新 洗牌。而在Tez中,几个reduce接收器可以直接连接,数据可以流水线传输,而不需要临时HDFS文件, 这种模式称为MRR(Map-reduce-reduce)。
    Tez还允许一次发送整个查询计划,实现应用程序动态规划,从而使框架能够更智能地分配资源,并通 过各个阶段流水线传输数据。对于更复杂的查询来说,这是一个巨大的改进,因为它消除了IO/sync障碍 和各个阶段之间的调度开销。
    在MapReduce计算引擎中,无论数据大小,在洗牌阶段都以相同的方式执行,将数据序列化到磁盘,再 由下游的程序去拉取,并反序列化。Tez可以允许小数据集完全在内存中处理,而MapReduce中没有这样 的优化。仓库查询经常需要在处理完大量的数据后对小型数据集进行排序或聚合,Tez的优化也能极大 地提升效率。
    2、存储引擎
    Hive的文件存储格式(存储引擎)有四种: TEXTFILE 、 SEQUENCEFILE 、 、 PARQUET ,前面两
    ORC
    种是行式存储,后面两种是列式存储。如果为textfile的文件格式,直接load,不需要走MapReduce;如 果是其他的类型就需要走MapReduce了,因为其他的类型都涉及到了文件的压缩,这需要借助MapReduce的压缩方式来实现。
    TEXTFILE :按行存储,不支持块压缩,默认格式,数据不做压缩,磁盘开销大,加载数据的速度最高

    RCFILE
    数据按行分块,每块按列存储,结合了行存储和列存储的优点RCFile 保证同一行的数据位于同一节点,因此元组重构的开销很低RCFile 能够利用列维度的数据压缩,并且能跳过不必要的列读取

ORCFile :
存储方式:数据按行分块,每块按照列存储压缩快,快速列存取
效率比rcfile高,是rcfile的改良版本,使用了索引
使用ORC文件格式可以提高hive读、写和处理数据的能力
PARQUET :按列存储,相对于ORC,Parquet压缩比较低,查询效率较低

SequenceFile
Hadoop API提供的一种二进制文件,以<key,value>的形式序列化到文件中存储方式:行存储
总结
压缩比:ORC > Parquet > textFile(textfile没有进行压缩)

查询速度:三者几乎一致

Hive的文件存储格式都有哪些
可回答:Hive四种文件类型和压缩情况
问过的一些公司:Shopee(2021.07)x2,贝壳找房(2021.11) 参考答案:
Hive的文件存储格式有四种: TEXTFILE 、 SEQUENCEFILE 、
ORC

、 PARQUET ,前面两种是行式存
储,后面两种是列式存储。如果为textfile的文件格式,直接load,不需要走MapReduce;如果是其他的 类型就需要走MapReduce了,因为其他的类型都涉及到了文件的压缩,这需要借助MapReduce的压缩方 式来实现。
TEXTFILE :按行存储,不支持块压缩,默认格式,数据不做压缩,磁盘开销大,加载数据的速度最高

RCFILE
数据按行分块,每块按列存储,结合了行存储和列存储的优点RCFile 保证同一行的数据位于同一节点,因此元组重构的开销很低RCFile 能够利用列维度的数据压缩,并且能跳过不必要的列读取

ORCFile :
存储方式:数据按行分块,每块按照列存储压缩快,快速列存取
效率比rcfile高,是rcfile的改良版本,使用了索引
使用ORC文件格式可以提高hive读、写和处理数据的能力
PARQUET :按列存储,相对于ORC,Parquet压缩比较低,查询效率较低

SequenceFile
Hadoop API提供的一种二进制文件,以<key,value>的形式序列化到文件中存储方式:行存储
总结
压缩比:ORC > Parquet > textFile(textfile没有进行压缩) 查询速度:三者几乎一致
Hive中如何调整Mapper和Reducer的数目
问过的一些公司:小米,美团,快手参考答案:
调整Mapper数量
之前MapReduce部分也有提到这个类似的问题
map数量=split数量
split数量=文件大小/split size
splitszie=Math.max(minSize, Math.min(maxSize, blockSize))
默认情况下,split size=blockSize,也就是128M

控制Mapper数量

1
2
3
4
set mapred.max.split.size=256000000;
set mapred.min.split.size.per.node=1; set mapred.min.split.size.per.rack=1;
– 决定每个map处理的最大的文档大小,单位为B
– 节点中可以处理的最小的文档大小
– 机架中可以处理的最小的文档大小
其设置原则就是

  1. 要增加map的个数,调整maxSize<blockSize;

  2. 要减小map的个数,调整minSize>blockSize。
    3
    调整Reducer数量
    修改下面两个参数就行

  3. 方法1

  4. set mapred.reduce.tasks=10; – 设置reduce的数量

  5. 方法2

  6. set hive.exec.reducers.bytes.per.reducer=1073741824 – 每个reduce处理的数据量,默认1GB 5

  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据小理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值