大数据面试知识点梳理

2023-10-27

1、hadoop是什么

Hadoop是一个由Apache基金会所开发的分布式系统基础架构,主要解决海量数据存储与计算的问题,其中主要包括HDFS、MapReduce和Yarn框架。

2、HDFS

HDFS四大机制:心跳机制,安全机制,机架策略(副本存放策略),负载均衡。
HDFS两大核心:文件上传和文件下载

2.0.1、心跳机制

介绍:hdfs是主从架构,所有为了实时的得知dataNode是否存活,必须建立心跳机制,在整个hdfs运行过程中,dataNode会定时的向nameNode发送心跳报告已告知nameNode自己的状态。

心跳内容:
报告自己的存活状态,每次汇报之后都会更新维护的计数信息
向nameNode汇报自己的存储的block列表信息

心跳报告周期:
nameNode判断一个dataNode宕机的基准:
连续10次接收不到dataNode的心跳信息,和2次的检查时间。

2.0.2、安全机制

介绍:hdfs在启动的时候,首先会进入的安全模式中,当达到规定的要求时,会退出安全模式。在安全模式中,不能执行任何修改元数据信息的操作。
  
hdfs的元数据的介绍(三个部分):
抽象目录树
数据与块的对应关系(文件被切分成多少个块)
block块存放的位置信息

hdfs元数据的存储位置:
内存:内存中存储了一份完整的元数据信息(抽象目录树、数据与块的对应关系、block块存放的位置信息)
硬盘:抽象目录树、数据与块的对应关系

2.0.3、机架策略(副本存放策略)

方法:将每个文件的数据进行分块存储,每一个数据块又保存有多个副本,这些数据块副本分
布在不同的机器节点上

2.0.4、负载均衡

hdfs集群中的每一个datanode上的存储的数据和自己的硬件占比是相当的;
这个时候我们可以认为这个hdfs集群是负载均衡的。

2.0.5、Hdfs两大核心

文件上传:hdfs写数据
文件下载:hdfs读数据

2.1、关于HDFS

Hive的数据存储在HDFS。主要分为NameNode,DataNode,SecondaryNameNode三个模块。
简单来说,HDFS数据的文件元信息,包括位置、大小、分块信息等,都是保存在NameNode的内存中的(真正的数据是存储在DataNode)。每个对象约占用150个字节,因此一千万个文件及分块就会占用约3G的内存空间(每个小文件都会占用NameNode模块的存储资源),一旦接近这个量级,NameNode的性能就会开始下降了。此外,HDFS读写小文件时也会更加耗时,因为每次都需要从NameNode获取元信息,并与对应的DataNode建立连接,读取数据。对于MapReduce程序来说,小文件还会增加Mapper的个数,每个脚本只处理很少的数据,浪费了大量的调度时间。当然这个问题可以通过使用CombinedInputFile和JVM重用来解决。

2.2、关于HDFS的读流程

在这里插入图片描述

2.3、关于HDFS的写流程

在这里插入图片描述
1、首先客户端会向namenode进行请求,然后namenode会检查该文件是否已经存在,如果不存在,就会允许客户端上传文件;
2、客户端再次向namenode请求第一个block上传到哪几个datanode节点上,假设namenode返回了三个datanode节点;
3、那么客户端就会向datanode1请求上传数据,然后datanode1会继续调用datanode2,datanode2会继续调用datanode3,那么这个通信管道就建立起来了,紧接着dn3,dn2,dn1逐级应答客户端;
4、然后客户端就会向datanode1上传第一个block,以packet为单位(默认64k),datanode1收到后就会传给datanode2,dn2传给dn3
5、当第一个block传输完成之后,客户端再次请求namenode上传第二个block。【写的时候,是串行的写入数据块】

2.4、关于HDFS中的小文件

小文件的产生原因:
1、动态分区插入数据的时候,会产生大量的小文件(动态分区产生小文件原因:在一段sql中指定两个字段当动态分区,一个字段的基数为7,另一个为4,这就是28个分区,数据插入动态分区阶段只有map任务,假如有4000个map,这种情况下map任务在往hive分区中写的时候,每个map几乎都要产生28个文件,这样就会产生4000*28个文件,带来大量的小文件);
2、数据源本身就包含有大量的小文件;
3、Reduce数量的增加,即意味结果文件的增加,从而产生小文件的问题。

2.4.1、小文件的影响

1、从HIVE角度来看的话呢,小文件越多,map的个数也会越多,每一个map都会开启一个JVM虚拟机,每个虚拟机都要创建任务,执行任务,这些流程都会造成大量的资源浪费,严重影响性能;
2、在HDFS中,每个小文件约占150byte,如果小文件过多则会占用大量的内存。这样namenode内存容量严重制约了集群的发展。

2.4.2、​小文件的解决方案

1、从小文件的产生途径解决:
1)使用sequencefile作为表存储形式,不要使用textfile,在一定程度上可以减少小文件;
2)减少reduce的个数(减少生成分区数量);
3)少用动态分区,使用distribute by分区。

2、对已经存在的小文件做出的解决方案:
1)使用Hadoop archive把小文件进行归档
Hadoop的归档文件格式也是解决小文件问题的方式之一。而且Hive提供了原生支持:

set hive.archive.enabled=true;
set hive.archive.har.parentdir.settable=true;
set har.partfile.size=1099511627776;
alter table srcpart archive partition(ds='2008-04-08', hr='12');
alter table srcpart unarchive partition(ds='2008-04-08', hr='12');

如果使用的不是分区表,则可创建成外部表,并使用har://协议来指定路径。
2)HDFS Federation
Hadoop V2引入了HDFS Federation的概念
实则是将NameNode做了拆分,从而增强了它的扩展性,小文件的问题也能够得到缓解。
3)重建表,建表时减少reduce的数量
4)通过参数调节,设置map/reduce的数量,对于通常的应用,使用Hive结果合并就能达到很好的效果。
设置map输入合并小文件的相关参数:

//每个Map最大输入大小(这个值决定了合并后文件的数量)
set mapred.max.split.size=256000000;
//一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
set mapred.min.split.size.per.node=100000000;
//一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)
set mapred.min.split.size.per.rack=100000000;
//执行Map前进行小文件合并
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

设置map输出和reduce输出进行合并的相关参数:

//设置map端输出进行合并,默认为true
set hive.merge.mapfiles = true;
//设置reduce端输出进行合并,默认为false
set hive.merge.mapredfiles = true;
//设置合并文件的大小
set hive.merge.size.per.task = 256*1000*100;
//当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge。
set hive.merge.smallfiles.avgsize=16000000;

2.5、数据存储和压缩

2.5.1、数据存储

    Hive底层数据是以HDFS文件的形式存储在Hadoop中的,选择一个合适的文件存储格式及压缩方式,也是 Hive 优化的一个重点。不同的文件存储格式及压缩格式,同时代表着不同的数据存储组织方式,对于性能优化表现会有很大不同。
2.5.1.1、行存储与列存储

数据处理大致可分为两大类,联机事务处理 OLTP(on-line transaction processing),联机分析处理 OLAP(On-Line Analytical Processing)。OLTP 是传统关系型数据库,主要应用来执行一些基本的、日常的事务处理,比如数据库记录的增、删、改、查等等;而OLAP则是分布式数据库,主要应用它对实时性要求不高,但处理数据量大,通常应用于复杂计算的报表系统上。

数据处理类型 OLTP OLAP
主要的面向对象 业务开发人员 分析决策人员
功能实现 日常事务处理 面向决策分析
数据模型 关系模型 多维模型
处理的数据量 通常几条或几十条 通常百万千万条
操作类型 查询、插入、更新、删除 查询为主
2.5.1.2、行存储的特点

1、查询满足条件的一整行数据的时,只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。
2、传统的关系型数据库,如Oracle、DB2、MySQL、SQL SERVER 等采用行式存储法(Row-based),在基于行式存储的数据库中,数据是按照行数据为基础逻辑存储单元进行存储的, 一行中的数据在存储中以连续存储形式存在。
3、这种存储格式比较方便进行INSERT/UPDATE操作,不足之处就是如果查询只涉及某几个列,它会把整行数据都读取出来,不能跳过不必要的列读取。当然数据比较少,一般没啥问题,如果数据量比较大就比较影响性能。还有就是由于每一行中,列的数据类型不一致,导致不容易获得一个极高的压缩比,也就是空间利用率不高。

2.5.1.3、列存储的特点

1、查询时,只有涉及到的列才会被查询,即可以跳过不必要的列查询,在查询只需要少数几个字段的时候,能大大减少读取的数据量;因为每一列的数据都是存储在一起的,每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法,高效的压缩率,不仅节省储存空间也节省计算内存和CPU;
2、不足之处是INSERT/UPDATE很麻烦或者不方便,不适合扫描小量的数据;
3、列式存储(Column-based)是相对于行式存储来说的,新兴的Hbase、HPVertica、EMCGreenplum等分布式数据库均采用列式存储。在基于列式存储的数据库中,数据是按照列为基础逻辑存储单元进行存储的,一列中的数据在存储介质中以连续存储形式存在。
在这里插入图片描述

2.5.1.4、Hive 存储格式有哪些?

Hive支持的存储数据的格式主要有:TEXTFILE 文本格式文件(行式存储)、 SEQUENCEFILE 二进制序列化文件(行式存储)、ORC(列式存储)、PARQUET(列式存储)等。
1、Hive 中的 TEXTFILE 文件存储格式
TEXTFILE 是 Hive 默认文件存储方式,存储方式为行存储,数据不做压缩,磁盘开销大,数据解析开销大,数据不支持分片,数据加载导入方式可以通过LOAD和INSERT两种方式加载数据。
可结合Gzip、Bzip2使用(系统自动检查,执行查询时自动解压),但使用gzip方式,hive不会对数据进行切分,从而无法对数据进行并行操作,但压缩后的文件不支持split。在反序列化过程中,必须逐个字符判断是不是分隔符和行结束符,因此反序列化开销会比SequenceFile高几十倍。
建表语句是:stored as textfile

2、Hive 中的 SequenceFile 文件存储格式
一种二进制文件,以key-value的形式序列化到文件中,存储方式为行式存储,sequencefile支持三种压缩选择:NONE,RECORD,BLOCK。Record压缩率低,RECORD是默认选项,通常BLOCK会带来较RECORD更好的压缩性能,自身支持切片。
数据加载导入方式可以通过INSERT方式加载数据,现阶段基本上不用。
建表语句是:sorted as sequencefile

3、Hive 中的常用文件存储格式 ORCFILE
保存在文件系统上的普通二进制文件,ORCFile是RCFile的优化版本,存储方式为行列存储,具体操作是将数据按照行分块,每个块按照列存储,其中每个块都存储有一个索引,自身支持切片,数据加载导入方式可以通过INSERT方式加载数据;
自身支持两种压缩ZLIB和SNAPPY,其中ZLIB压缩率比较高,常用于数据仓库的ODS层,SNAPPY压缩和解压的速度比较快,常用于数据仓库的DW层,需要注意的是 ORC在读写时候需要消耗额外的CPU资源来压缩和解压缩,当然这部分的CPU消耗是非常少的;
相比TEXTFILE和SEQUENCEFILE,RCFILE由于列式存储方式,数据加载时性能消耗较大,但是具有较好的压缩比和查询响应。数据仓库的特点是一次写入、多次读取,因此,整体来看,RCFILE相比其余两种格式具有较明显的优势。
建表语句是:sorted as orc

4、Hive 中的常用文件存储格式 Parquet
Parquet 是面向分析型业务的列式存储格式,由Twitter和Cloudera合作开发,2015年5月从Apache的孵化器里毕业成为Apache顶级项目。
是一个面向列的二进制文件格式,所以是不可以直接读取的,文件中包括该文件的数据和元数据,因此Parquet格式文件是自解析的。Parquet一般使用Snappy、Gzip压缩,默认是Snappy(数据不可切分)。同时Parquet是语言无关的,而且不与任何一种数据处理框架绑定在一起,适配多种语言和组件。
建表语句是:sorted as Parquet

2.5.2、数据的压缩

2.5.2.1、压缩概述

1、压缩技术能够有效减少底层存储系统(HDFS)读写字节数。压缩提高了网络传输(由于压缩后的数据占用的带宽更少,因此可以加快数据在Hadoop集群流动的速度)和磁盘空间的效率。在运行MR程序时,I/O操作、网络数据传输、 Shuffle和Merge要花大量的时间,尤其是数据规模很大和工作负载密集的情况下,因此,使用数据压缩显得非常重要。
2、鉴于磁盘I/O和网络带宽是Hadoop的宝贵资源,数据压缩对于节省资源、最小化磁盘I/O和网络传输非常有帮助。可以在任意MapReduce阶段启用压缩。不过尽管压缩与解压操作的CPU开销不高,其性能的提升和资源的节省并非没有代价。
3、压缩策略与原则
压缩是提高Hadoop运行效率的一种优化策略。通过对Mapper、Reducer运行过程的数据进行压缩,以减少磁盘IO,提高MR程序运行速度。
4、注意:采用压缩技术减少了磁盘IO,但同时增加了CPU运算负担。所以,压缩特性运用得当能提高性能,但运用不当也可能降低性能。
5、压缩基本原则:
运算密集型的job,少用压缩
IO密集型的job,多用压缩

2.5.2.2、MR支持的压缩编码

在这里插入图片描述
在这里插入图片描述
其中压缩比来看,bzip2 > zlib > gzip > deflate > Lzo > snappy > lz4,在不同的测试场景中,会有差异,这仅仅是一个大概的排名情况。bzip2、zlib、gzip、deflate可以保证最小的压缩,但在运算中过于消耗时间。

从压缩性能上来看,lz4 > snappy > Lzo > deflate > gzip > bzip2,其中lz4、lzo、snappy压缩和解压缩速度快,压缩比低。

所以一般在生产环境中,经常会采用lz4、lzo、snappy压缩,以保证运算效率。

2.5.2.3、压缩方式选择

1、Gzip压缩
优点:压缩率比较高,而且压缩/解压速度也比较快;Hadoop本身支持,在应用中处理Gzip格式的文件就和直接处理文本一样;大部分Linux系统都自带Gzip命令,使用方便。
缺点:不支持Split。
应用场景:当每个文件压缩之后在130M以内的(1个块大小内),都可以考虑用Gzip压缩格式。例如说一天或者一个小时的日志压缩成一个Gzip文件。

2、Bzip2压缩
优点:支持Split;具有很高的压缩率,比Gzip压缩率都高;Hadoop本身自带,使用方便。
缺点:压缩/解压速度慢。
应用场景:适合对速度要求不高,但需要较高的压缩率的时候;或者输出之后的数据比较大,处理之后的数据需要压缩存档减少磁盘空间并且以后数据用得比较少的情况;或者对单个很大的文本文件想压缩减少存储空间,同时又需要支持Split,而且兼容之前的应用程序的情况。

3、Lzo压缩
优点:压缩/解压速度也比较快,合理的压缩率;支持Split,是Hadoop中最流行的压缩格式;可以在Linux系统下安装lzop命令,使用方便。
缺点:压缩率比Gzip要低一些;Hadoop本身不支持,需要安装;在应用中对Lzo格式的文件需要做一些特殊处理(为了支持Split需要建索引,还需要指定InputFormat为Lzo格式)。
应用场景:一个很大的文本文件,压缩之后还大于200M以上的可以考虑,而且单个文件越大,Lzo优点越越明显。

4、Snappy压缩
优点:高速压缩速度和合理的压缩率。
缺点:不支持Split;压缩率比Gzip要低;Hadoop本身不支持,需要安装。
应用场景:当MapReduce作业的Map输出的数据比较大的时候,作为Map到Reduce的中间数据的压缩格式;或者作为一个MapReduce作业的输出和另外一个MapReduce作业的输入。

2.5.2.4、Map和Reduce输出阶段压缩

1、开启map输出阶段压缩可以减少job中map和Reduce task间数据传输量。具体配置如下:

--1、开启hive中间传输数据压缩功能
set hive.exec.compress.intermediate=true;
--2、开启mapreduce中map输出压缩功能
set mapreduce.map.output.compress=true;
--3、设置mapreduce中map输出数据的压缩方式
set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;

2、开启Reduce输出阶段压缩
当Hive将输出写入到表中时,输出内容同样可以进行压缩。属性hive.exec.compress.output控制着这个功能。用户可能需要保持默认设置文件中的默认值false,这样默认的输出就是非压缩的纯文本文件了。用户可以通过在查询语句或执行脚本中设置这个值为true,来开启输出结果压缩功能。

--1、开启hive最终输出数据压缩功能
set hive.exec.compress.output=true;
--2、开启mapreduce最终输出数据压缩
set mapreduce.output.fileoutputformat.compress=true;
--3、设置mapreduce最终数据输出压缩方式
set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;
--4、设置mapreduce最终数据输出压缩为块压缩
set mapreduce.output.fileoutputformat.compress.type=BLOCK;
--5、测试一下输出结果是否是压缩文件
insert overwrite local directory
 '/opt/module/hive/datas/distribute-result' select * from emp distribute 
2.5.2.5、总结

1、数据压缩可以发生在哪些阶段:
1)输入数据可以压缩后的数据
2)中间的数据可以压缩
3)输出的数据可以压缩
2、hive 仅仅是配置了开启压缩和使用哪种压缩方式,真正的配置是在hadoop 中配置的,而数据的压缩是在MapReduce 中发生的
3、对于数据密集型任务,I/O操作和网络数据传输需要花费相当长的时间才能完成。通过在 Hive 中启用压缩功能,我们可以提高 Hive 查询的性能,并节省 HDFS 集群上的存储空间。

2.6、YARN的基本组件和运行原理

YARN,全称Yet Another Resource Negotiator,中文名为另一种资源协调者,是一种新的Hadoop资源管理器。

2.6.1、YARN的相关组成

YARN上含有以下几个重要的组件:

ResourceManager:简称为RM,负责管理所有应用程序计算资源的分配,是一个全局的资源管理系统,定期接收来自NodeManager关于本机的资源使用情况。ResourceManager只负责集群整体的资源管理,各个节点的具体资源的处理由节点上的NodeManager自己实现,生产环境上通常为高可用模式,即设置主备节点,主节点状态为Active,备节点状态为Standby。当主节点发生异常时,会实现切换,从节点会自动升级为主节点。

NodeManager:简称为NM,管理所在机器的代理,负责本机程序运行,资源管理和监控,集群中每个NM节点上的NM服务会定时向RM汇报本节点的资源使用情况和Container运行情况,如果判断主RM通信失败,NM会立即连接备用的RM处理作用任务。

ApplicationMaster:简称为AM,每当提交一个应用程序便会产生一个用以跟踪和管理该程序的AM,该AM负责向ResourceManager申请资源,由AMLancher与对应NodeManager联系并启动常驻在NodeManager中的AM,该AM将获得资源的容器Container,一个任务对应一个Container,用于任务的运行,监控,如果任务运行失败,系统将会重新为其申请资源和启动任务。

Container
Container是YARN中的资源抽象,它封装了某个节点上的多维度资源,如内存、CPU、磁盘、网络等,当AM向RM申请资源时,RM为AM返回的资源便是用Container表示的。当前仅支持内存和CPU。
YARN会为每个任务分配一个Container,且该任务只能使用该Container中描述的资源。
Container是一个动态资源划分单位,是根据应用程序的需求动态生成的。

2.6.2、Yarn执行流程

当用户向YARN中提交一个应用程序后,YARN将分两个阶段运行该应用程序:

第一个阶段是启动ApplicationMaster;
第二个阶段是由ApplicationMaster创建应用程序,为它申请资源,并监控它的整个运行过程,直到运行完成。YARN的工作流程分为以下几个步骤:

步骤1、用户向YARN中提交应用程序,其中包括ApplicationMaster程序、启动ApplicationMaster的命令、用户程序等。
步骤2、ResourceManager为该应用程序分配第一个Container,并与对应的NodeManager通信,要求它在这个Container中启动应用程序的ApplicationMaster。
步骤3、ApplicationMaster首先向ResourceManager注册,这样用户可以直接通过ResourceManage查看应用程序的运行状态,然后它将为各个任务申请资源,并监控它的运行状态,直到运行结束,即重复步骤4~7。
步骤4、ApplicationMaster采用轮询的方式通过RPC协议向ResourceManager申请和领取资源。
步骤5、一旦ApplicationMaster申请到资源后,便与对应的NodeManager通信,要求它启动任务。
步骤6、NodeManager为任务设置好运行环境(包括环境变量、JAR包、二进制程序等)后,将任务启动命令写到一个脚本中,并通过运行该脚本启动任务。
步骤7、各个任务通过某个RPC协议向ApplicationMaster汇报自己的状态和进度,以让ApplicationMaster随时掌握各个任务的运行状态,从而可以在任务失败时重新启动任务。
在应用程序运行过程中,用户可随时通过RPC向ApplicationMaster查询应用程序的当前运行状态。
步骤8、应用程序运行完成后,ApplicationMaster向ResourceManager注销并关闭自己。

3、HiveSQL转化Mapreduce执行过程

    Hive是什么?Hive 是数据仓库工具,再具体点就是一个 SQL 解析引擎,因为它即不负责存储数据,也不负责计算数据,只负责解析 SQL,记录元数据。

Hive访问存储在 HDFS 中或者 HBase 中的文件,通过 MapReduce、Spark 或 Tez 来执行查询。
那么Hive 底层是怎样将SQL 转化为 MapReduce 等计算引擎可识别的程序。了解 Hive SQL 的底层编译过程有利于我们优化Hive SQL,提升我们对Hive的掌控力。

3.1、Hive的底层执行架构

Hive 的主要组件与 Hadoop 交互的过程:
在这里插入图片描述
在 Hive 这一侧,总共有五个组件:

UI:用户界面。可看作我们提交SQL语句的命令行界面。

DRIVER:驱动程序。接收查询的组件。该组件实现了会话句柄的概念。

COMPILER:编译器。负责将 SQL 转化为平台可执行的执行计划。对不同的查询块和查询表达式进行语义分析,并最终借助表和从 metastore 查找的分区元数据来生成执行计划。

METASTORE:元数据库。存储 Hive 中各种表和分区的所有结构信息。

EXECUTION ENGINE:执行引擎。负责提交 COMPILER 阶段编译好的执行计划到不同的平台上。

上图的基本流程是:

步骤1:UI 调用 DRIVER 的接口;

步骤2:DRIVER 为查询创建会话句柄,并将查询发送到 COMPILER(编译器)生成执行计划;

步骤3和4:编译器从元数据存储中获取本次查询所需要的元数据,该元数据用于对查询树中的表达式进行类型检查,以及基于查询谓词修建分区;

步骤5:编译器生成的计划是分阶段的DAG,每个阶段要么是 map/reduce 作业,要么是一个元数据或者HDFS上的操作。将生成的计划发给 DRIVER。

如果是 map/reduce 作业,该计划包括 map operator trees 和一个 reduce operator tree,执行引擎将会把这些作业发送给 MapReduce :

步骤6、6.1、6.2和6.3:执行引擎将这些阶段提交给适当的组件。在每个 task(mapper/reducer) 中,从HDFS文件中读取与表或中间输出相关联的数据,并通过相关算子树传递这些数据。最终这些数据通过序列化器写入到一个临时HDFS文件中(如果不需要 reduce 阶段,则在 map 中操作)。临时文件用于向计划中后面的 map/reduce 阶段提供数据。

步骤7、8和9:最终的临时文件将移动到表的位置,确保不读取脏数据(文件重命名在HDFS中是原子操作)。对于用户的查询,临时文件的内容由执行引擎直接从HDFS读取,然后通过Driver发送到UI。

3.2、HiveSQL编译成MapReduce过程

编译SQL的任务是在上节中介绍的COMPILER(编译器组件)中完成的。Hive将SQL转化为MapReduce任务,整个编译过程分为六个阶段:
在这里插入图片描述
HiveSQL编译过程

1、词法、语法解析:Antlr 定义 SQL 的语法规则,完成 SQL 词法,语法解析,将 SQL 转化为抽象语法树 AST Tree;

2、语义解析:遍历 AST Tree,抽象出查询的基本组成单元 QueryBlock;

3、生成逻辑执行计划:遍历 QueryBlock,翻译为执行操作树 OperatorTree;

4、优化逻辑执行计划:逻辑层优化器进行 OperatorTree 变换,合并 Operator,达到减少 MapReduce Job,减少数据传输及 shuffle 数据量;

5、生成物理执行计划:遍历 OperatorTree,翻译为 MapReduce 任务;

6、优化物理执行计划:物理层优化器进行 MapReduce 任务的变换,生成最终的执行计划。

下面对这六个阶段详细解析:
我们拿一个简单的查询语句进行展示,对5月23号的地区维表进行查询:

select * from dim.dim_region where dt = '2021-05-23';

阶段一:词法、语法解析
根据Antlr定义的sql语法规则,将相关sql进行词法、语法解析,转化为抽象语法树AST Tree:

ABSTRACT SYNTAX TREE:
TOK_QUERY
    TOK_FROM 
    TOK_TABREF
           TOK_TABNAME
               dim
                 dim_region
    TOK_INSERT
      TOK_DESTINATION
          TOK_DIR
              TOK_TMP_FILE
        TOK_SELECT
          TOK_SELEXPR
              TOK_ALLCOLREF
        TOK_WHERE
          =
              TOK_TABLE_OR_COL
                  dt
                    '2021-05-23'

阶段二:语义解析
遍历AST Tree,抽象出查询的基本组成单元QueryBlock:

AST Tree生成后由于其复杂度依旧较高,不便于翻译为mapreduce程序,需要进行进一步抽象和结构化,形成QueryBlock。

QueryBlock是一条SQL最基本的组成单元,包括三个部分:输入源,计算过程,输出。简单来讲一个QueryBlock就是一个子查询。

QueryBlock的生成过程为一个递归过程,先序遍历 AST Tree ,遇到不同的 Token 节点(理解为特殊标记),保存到相应的属性中。

阶段三:生成逻辑执行计划
遍历QueryBlock,翻译为执行操作树OperatorTree:

Hive最终生成的MapReduce任务,Map阶段和Reduce阶段均由OperatorTree组成。

基本的操作符包括:
TableScanOperator
SelectOperator
FilterOperator
JoinOperator
GroupByOperator
ReduceSinkOperator

Operator在Map Reduce阶段之间的数据传递都是一个流式的过程。每一个Operator对一行数据完成操作后之后将数据传递给childOperator计算。

由于Join/GroupBy/OrderBy均需要在Reduce阶段完成,所以在生成相应操作的Operator之前都会先生成一个ReduceSinkOperator,将字段组合并序列化为Reduce Key/value, Partition Key。

阶段四:优化逻辑执行计划
Hive中的逻辑查询优化可以大致分为以下几类:

投影修剪
推导传递谓词
谓词下推
将Select-Select,Filter-Filter合并为单个操作
多路 Join
查询重写以适应某些列值的Join倾斜

阶段五:生成物理执行计划

生成物理执行计划即是将逻辑执行计划生成的OperatorTree转化为MapReduce Job的过程,主要分为下面几个阶段:

1、对输出表生成MoveTask
2、从OperatorTree的其中一个根节点向下深度优先遍历
3、ReduceSinkOperator标示Map/Reduce的界限,多个Job间的界限
4、遍历其他根节点,遇过碰到JoinOperator合并MapReduceTask
5、生成StatTask更新元数据
6、剪断Map与Reduce间的Operator的关系

阶段六:优化物理执行计划
Hive中的物理优化可以大致分为以下几类:

1、分区修剪(Partition Pruning)
2、基于分区和桶的扫描修剪(Scan pruning)
3、如果查询基于抽样,则扫描修剪
4、在某些情况下,在 map 端应用 Group By
5、在 mapper 上执行 Join
6、优化 Union,使Union只在 map 端执行
7、在多路 Join 中,根据用户提示决定最后流哪个表
8、删除不必要的 ReduceSinkOperators
9、对于带有Limit子句的查询,减少需要为该表扫描的文件数
10、对于带有Limit子句的查询,通过限制 ReduceSinkOperator 生成的内容来限制来自 mapper 的输出
11、减少用户提交的SQL查询所需的Tez作业数量
12、如果是简单的提取查询,避免使用MapReduce作业
13、对于带有聚合的简单获取查询,执行不带 MapReduce 任务的聚合
14、重写 Group By 查询使用索引表代替原来的表
15、当表扫描之上的谓词是相等谓词且谓词中的列具有索引时,使用索引扫描

3.2.1、hive中逻辑查询计划和物理查询计划优化的区别

1、逻辑查询计划(Logical Query Plan)优化
逻辑查询计划是指查询语句的逻辑表示,它描述了查询的逻辑操作和数据流,而不考虑具体的执行细节和物理资源。逻辑查询计划优化主要关注查询语句的逻辑结构和语义,以提高查询的效率和性能。
在逻辑查询计划优化阶段,Hive会执行以下优化操作:
1)表达式合并和重写:将具有相同含义或等效的表达式合并或替换为更简洁的形式,减少计算量。
2)谓词下推:将过滤条件尽可能下推至数据源,减少数据的读取量。
3)投影消除:根据查询需求,优化查询结果的投影操作,减少数据传输和处理的成本。
4)子查询优化:重新组织子查询的执行顺序或使用更有效的方法进行计算,减少计算量或数据传输。
5)聚合优化:对于聚合操作,优化计算顺序、使用部分聚合或使用索引等技术,减少计算和数据传输。

2、物理查询计划(Physical Query Plan)优化
物理查询计划是将逻辑查询计划转换为实际执行计划(如MapReduce任务、Tez任务等)的过程,它考虑了数据的物理存储和计算资源的分配等因素。
在物理查询计划优化阶段,Hive会执行以下优化操作:
1)数据本地化和数据倾斜处理:根据数据的分布情况和计算资源的位置,将计算任务尽可能分配到数据所在的节点,减少数据的网络传输。
2)扫描和过滤优化:根据查询的过滤条件、数据分区和索引等,选择最优的扫描方法和过滤顺序,减少不必要的数据读取和处理。
3)Join优化:通过选择最适合的Join算法、Join顺序和Join类型等优化技术,提高Join操作的性能。
4)资源分配和并行度控制:根据集群资源和查询需求,调整并发任务的数量和资源分配,达到最佳的查询性能。

总结
逻辑查询计划优化主要关注查询语句的语义和结构,采用逻辑优化技术来改进查询的逻辑执行过程。而物理查询计划优化则关注实际的执行计划,针对底层数据存储和物理资源进行优化,以获得最佳的查询性能。这两个阶段的优化相互补充,共同作用于Hive查询的各个层次,以提高查询的效率和性能。

3.3、MapReduce的运行完整流程

MapReduce是面向大数据并行处理的计算框架和平台,提供数据划分和任务计算调度的功能,系统自动将一个待处理的大数据作业(Job)划分为很多个数据块,每个数据块对应一个计算任务(Task),并调度计算节点来处理相应的数据块。

3.3.1、MapReduce工作流程

MapReduce 整体包含:MapTask、Map到Reduce数据传输的Shuffle、ReduceTask。
在这里插入图片描述

MapTask过程:
1、Read阶段:MapTask通过InputFormat获得的RecordReader,从输入InputSplit中解析出一个个Key-Value。
2、Map阶段:该节点主要是将解析出的Key-Value交给用户编写map()函数处理,并产生一系列新的Key-Value。
3、Collect收集阶段:在用户编写map()函数中,当数据处理完成后,一般会调用OutputCollector.collect()输出结果。在该函数内部,它会将生成的Key-Value分区(调用Partitioner),并写入一个环形内存缓冲区中。
4、Spill阶段:即“溢写”,当环形缓冲区满后,MapReduce会将数据写到本地磁盘上,生成一个临时文件。需要注意的是,将数据写入本地磁盘之前,先要对数据进行一次本地排序,并在必要时对数据进行合并、压缩等操作。
5、Merge阶段:当所有数据处理完成后,MapTask对所有临时文件进行一次合并,以确保最终只会生成一个数据文件。

写入环形内存缓冲区,这种设计有以下几个原因:

1、减少磁盘I/O:将中间结果暂存在内存中,可以减少对磁盘的读写操作。相比将所有数据直接写入磁盘,将部分数据暂存在内存缓存区可以大大提高性能。

2、合并相同键的数据:在环形内存缓存区中,相同键的数据可以被合并。这样可以减少后续处理阶段的数据量,降低存储和网络传输的开销。

3、提高局部性:由于环形内存缓存区是在计算节点上的内存中,它与计算节点上的其他处理原语(如排序、合并等)具有良好的局部性。因此,对于后续的计算操作,可以更高效地访问和处理这些数据。
当环形内存缓存区达到一定大小或达到某个阈值时,会将缓冲区中的数据临时写入磁盘,然后重新利用这块缓冲区。
总之,将部分数据写入环形内存缓存区是为了减少磁盘I/O,合并相同键的数据以及提高局部性,从而提高整体的计算性能和效率。

Shuffle过程:
Shuffle过程是指从Map输出到Redue输入的整个过程。Shuffle 阶段如下:
1、collect阶段:将 MapTask 的结果输出到默认大小为100M 环形缓冲区;
2、spill阶段:当内存中的数据量达到一定阈值 80M 时,就启动溢写线程,对这 80M 空间内的 key 进行排序;如果配置了 Combiner ,则预先进行聚合操作,最后会将数据溢写到本地磁盘;
3、merge 阶段:把所有溢写的临时文件进行合并,以确保一个 MapTask 最终只产生一个中间数据文件,并且为这个文件提供索引文件,用来记录每个 reducer 对应数据的偏移量;
4、copy 阶段:ReduceTask 启动 Fetcher 线程将 MapTask 节点上的属于自己的数据 copy 一份到内存缓冲区中,当内存缓冲区达到一定阈值时,就会将数据溢写到磁盘中;
5、merge 阶段:在 ReduceTask 远程复制数据的同时,会在后台开启两个线程对内存到本地的数据文件进行合并操作;
6、sort 阶段:在对数据进行合并的同时,会进行归并排序操作,由于 MapTask 阶段已经对数据进行了局部排序, ReduceTask 只需保证 copy 的数据最终整体有序即可。

ReduceTask过程:
1、Copy阶段:ReduceTask从各个MapTask上远程拷贝一片数据,并针对某一片数据,如果其大小超过一定阈值,则写到磁盘上,否则直接放到内存中。
2、Sort阶段:在远程拷贝数据的同时,ReduceTask启动了两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或磁盘上文件过多。按照MapReduce语义,用户编写reduce() 函数输入数据是按Key进行聚集的一组数据。为了将Key相同的数据聚在一起,Hadoop采用了基于排序的策略。由于各个MapTask已经实现对处理结果进行了局部排序,因此,ReduceTask只需对所有数据进行一次归并排序即可。
3、Reduce阶段:reduce() 函数将计算结果写到HDFS上。

3.3.2、map阶段的spill和shuffle阶段的spill有什么区别

在MapReduce任务中,"spill"是指当内存中的数据超过某个阈值时,将数据写入磁盘的过程。这个过程在Map阶段和Shuffle阶段都会发生,但是有一些区别:

Map阶段的Spill:
当Map任务处理输入数据时,它会尝试将输出键值对存储在内存缓冲区中。
当缓冲区达到某个阈值时,Map任务会触发Spill操作,将缓冲区中的部分数据溢写到本地磁盘。
Map任务会继续处理数据并将新数据写入缓冲区,同时将溢写的数据继续写入磁盘,所以可能会有多个spill文件。
Spill操作在Map阶段是并发执行的,不同的Map任务可以同时执行Spill操作。

Shuffle阶段的Spill:
在Shuffle阶段,Reducer任务从Map任务读取属于自己的数据分片(Partition),并进行合并排序以进行后续的Reduce操作。
当Reducer任务从多个Map任务读取数据时,内存中的缓冲区可能会填满。
当缓冲区达到某个阈值时,Reducer任务会触发Spill操作,将缓冲区中的数据写入本地磁盘。
Shuffle阶段的Spill是在Reducer端进行的,每个Reducer任务只能在单线程中执行一个Spill操作,这是为了保证数据的有序性。
Spill后的数据将进行合并和排序,并生成Reducer输入的最终输出。

总结:
Map阶段的Spill是在Map任务进行数据处理时,将溢写部分数据到磁盘,以释放内存缓冲区的空间。
Shuffle阶段的Spill是在Reducer任务读取Map任务输出的数据时,将溢写部分数据到磁盘,以保持合并排序的过程的内存使用可控。
Map阶段的Spill是并发执行的,多个Map任务可以同时进行Spill操作。而Shuffle阶段的Spill是在单线程中逐个进行的,以保证数据的有序性。
Spill操作在两个阶段都是将内存中的数据写入磁盘,以防止内存溢出,但具体实现和执行方式在Map阶段和Shuffle阶段有所不同。

4、Mapreduce任务优化

4.1、MapReduce跑的慢的原因

MapReduce程序效率的瓶颈在于两点:
1、计算机性能:
CPU、内存、磁盘健康、网络
关于计算机性能治理:
1、申请资源,按照目前项目运维每日最大的资源消耗情况来计算,以及业务发展增速,来申请新增CPU资源;
2、开展存量的任务治理,针对高消耗的任务进行监控,并对代码逻辑优化;
3、对目前的任务跑数时点进行分流,ods/核心数据在早晨0-2跑数,dwd层数据在2-4时点段跑数,避免资源之间进行过度竞争。
2、I/O 操作优化
数据倾斜
小文件过多
大量的不可分块的超大文件
大表join
Map 和 Reduce 数设置不合理
Map运行时间太长,导致 Reduce 等待过久
Spill 次数过多
Merge 次数过多等。

4.2、MapReduce优化

关于 MapReduce 优化方法主要从以下5个方面进行考虑,分别是:数据倾斜、Map阶段、Reduce阶段、IO传输、常用调优参数。
1、数据倾斜问题
数据倾斜现象:
数据频率倾斜——数据频率倾斜指某个列或分区中某个数据值的出现频率远高于其他数据值。
这可能发生在例如某个特定的用户ID、产品ID或者地理区域上。reduce端的数据倾斜

数据大小倾斜——某些文件的大小可能远大于其他文件。数据大小倾斜会导致某些节点的负载较重,可能会导致数据读取和处理的不均衡。map端的数据倾斜

针对数据频次倾斜处理方法:
情况1 :热点key值
1、join场景:首先通过行列,谓词下推等方式减少数据量
1)大表Join小表的情况:将小表缓存到内存中,采用mapjoin
2)大表join大表:

  • 将热点key单独拉出来(空key过滤,空key转换),将小表缓存到内存中,转换成hashtable,采用mapjoin,省去shuffle过程,避免Reduce阶段的数据倾斜,将处理得到的结果和其他表union起来;
  • 将主表key一列单独拉出来,与从表进行mapjoin过滤数据,再与主表关联;
  • 将关联的两个表union起来,没有的字段相互补null,然后通过groupby取最大值,就能得到关联的效果,将join过程的shuffle转化为groupby过程的shuffle(join过程更耗时),groupby聚合还可以转换两次聚合;
  • 增加并行度,通过增加JOIN操作的并行度,将负载均衡到更多的任务上。可以通过设置合适的参数来调整任务的并行度,例如hive.exec.reducers.bytes.per.reducer或hive.exec.reducers.max。这样可以减少热点key在单个任务上的聚集,并提高整体性能。

大表join 大表(sort merge bucket join)
分桶其实就是把大表化成了“小表”,然后 Map-Side Join解决之,这是典型的分而治之的思想。

思想:首先进行排序,继而合并,然后放到所对应的bucket中去,bucket是hive中和分区表类似的技术,就是按照key进行hash,相同的hash值都放到相同的buck中去。在进行两个表联合的时候。我们首先进行分桶,在join会大幅度的对性能进行优化。也就是说,在进行联合的时候,是table1中的一小部分和table1中的一小部分进行联合,table联合都是等值连接,相同的key都放到了同一个bucket中去了,那么在联合的时候就会大幅度的减小无关项的扫描。

限制条件:
1)针对参与join的这两张做相同的hash散列,每个桶里面的数据还要排序
2)这两张表的分桶个数要成倍数。
具体操作:

1) 首先设置如下:
set hive.auto.convert.sortmerge.join=true;
set hive.optimize.bucketmapjoin = true;//正常的情况下,应该是启动smbjoin的但是这里的数据量太小啦,还是启动了mapjoin
set hive.optimize.bucketmapjoin.sortedmerge = true;
set hive.auto.convert.sortmerge.join.noconditionaltask=true;
2) 小表的bucket数=大表bucket数 
3) Bucket 列 == Join== sort 列 
## 当用户执行bucket map join的时候,发现不能执行时,禁止查询
set hive.enforce.sortmergebucketmapjoin=false;

## 如果join的表通过sort merge join的条件,join是否会自动转换为sort merge join
set hive.auto.convert.sortmerge.join=true;

## 当两个分桶表 join 时,如果 join on的是分桶字段,小表的分桶数是大表的倍数时,可以启用mapjoin 来提高效率。
# bucket map join优化,默认值是 false
set hive.optimize.bucketmapjoin=false;
## bucket map join 优化,默认值是 false
set hive.optimize.bucketmapjoin.sortedmerge=false;

注意:
hive并不检查两个join的表是否已经做好bucket且sorted,需要用户自己去保证join的表,否则可能数据不正确。有两个办法

1)hive.enforce.sorting 设置为true2)手动生成符合条件的数据,通过在sql中用distributed c1 sort by c1 或者 cluster by c1 
表创建时必须是CLUSTERED且SORTED,如下 
create table test_smb_2(mid string,age_id string) 
CLUSTERED BY(mid) SORTED BY(mid) INTO 500 BUCKETS;

2、group by 统计场景:将key值前面拼接一个1-10的随机值,按照拼接后的key值做初步的统计,然后再按照原来的key值再做统计; 使用 Combine 开启map阶段的数据合并,可以减少reduce阶段的数据倾斜。尽量减少distinct统计,在

2、数据输入
1)合并小文件:在执行 MR 任务之前将小文件进行合并,大量的小文件会产生大量的 MR 任务,增大 Map 任务装载次数,而任务的装载比较耗时,从而导致 MR 运行较慢。
2)采用 CombineText InputFormat 来作为输入,解决输入端大量小文件场景。

3、Map阶段
1)减少溢写(spill)次数:通过调整 io.sort.mb 及 sort.spill.percent 参数值,增大触发 Spill 的内存上限,减少 Spill 次数,从而减少磁盘 IO 。
2)减少合并(Merge)次数:通过调整io.sort.factor参数,增大 Merge 的文件数目,减少 Merge 的次数,从而缩短 MR 处理时间。
3)在 Map 之后,不影响业务逻辑前提下,先进行 Combine 处理,减少 I/O 。

4、Reduce 阶段
1)合理设置 Map 和 Reduce 数:两个都不能设置的太少,也不能设置的太多。太少,会导致 Task 等待,延长处理时间;太多,会导致 Map,Reduce 任务间竞争资源,造成处理超时等错误 。
2)设置 Map、Reduce 共存:调整 slowstart.completedmap参数,使 Map 运行到一定程度后,Reduce 也开始运行,减少 Reduce 的等待时间 。
3)规避使用 Reduce:因为 Reduce 在用于连接数据集的时候将会产生大量的网络消耗。
4)合理设置 Reduce 端的 Buffer:默认情况下,数据达到一个阈值的时候,Buffer 中的数据就会写入磁盘,然后 Reduce 会从磁盘中获得所有的数据。也就是说,Buffer 和 Reduce 是没有直接关联的,中间多次写磁盘 -> 读磁盘的过程,既然有这个弊端,那么就可以通过参数来配置,使得 Buffer 中的一部分数据可以直接输送到 Reduce,从而减少 IO 开销 : mapreduce.reduce.input.buffer.percent,默认为 0.0 。当值大于 0 的时候,会保留指定比例的内存读 Buffer 中的数据直接拿给 Reduce 使用 。这样一来,设置 Buffer 需要内存,读取数据需要内存,Reduce 计算也需要内存,所以要根据作业的用运行情况进行调整 。

5、I/O 传输
1)采用数据压缩的方式,减少网络IO的时间 ,安装 Snappy 和 LZO 压缩编码器,对中间结果进行压缩,但是数据压缩和解压过程需要额外消耗CPU,需要根据实际情况来定。
2)使用SequenceFile二进制文件。

6、常用的调优参数
map端参数优化
1、小文件过多,map执行前合并小文件,减少map数量
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
2、对大文件进行切分,控制map任务最大读取的数据量,避免map端倾斜
set mapred.max.split.size=256000000;每个Map最大输入大小,默认值
每个Map最小输入大小
set mapred.min.split.size=10000000;每个Map最小输入大小,默认值
当input的文件都很大,任务逻辑复杂,map执行非常慢的时候,可以考虑增加Map数,来使得每个map处理的数据量减少,从而提高任务的执行效率。
3、开启map端部分聚合
set hive.map.aggr=true;默认值是true,当选项设定为true时,开启map端部分聚合,这样做减少了map端输出,减少了下游任务的shuffle数据量,减少了磁盘io,这个参数hive这总是默认开启,但是需要配合另外两个参数联调使用。分别是: hive.map.aggr.hash.min.reducetion和hive.groupby.mapaggr.checkinterval用于控制何时启用聚合

4、开启map输出阶段压缩可以减少job中map和Reduce task间数据传输量。具体配置如下:
开启hive中间传输数据压缩功能
set hive.exec.compress.intermediate=true;
开启mapreduce中map输出压缩功能
set mapreduce.map.output.compress=true;
设置mapreduce中map输出数据的压缩方式
set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
5、map阶段内存调整
set mapreduce.map.memory.mb=1024;
适当增加内存大小,可以减少spill溢写磁盘的次数,提高效率;

reduce参数优化
1、调节reducer个数
set hive.exec.reducers.bytes.per.reducer=256000000;
2、set hive.exec.reducers.bytes.per.reducer
设定每个reducer能够处理的数据量,默认值是256m
3、reducer阶段内存调整
set mapreduce.reduce.java.opts=-Xmx2048m;
set mapreduce.reduce.memory.mb=1024;
4、开启Reduce输出阶段压缩
当Hive将输出写入到表中时,输出内容同样可以进行压缩。属性hive.exec.compress.output控制着这个功能。用户可能需要保持默认设置文件中的默认值false,这样默认的输出就是非压缩的纯文本文件了。用户可以通过在查询语句或执行脚本中设置这个值为true,来开启输出结果压缩功能。
–1、开启hive最终输出数据压缩功能
set hive.exec.compress.output=true;
–2、开启mapreduce最终输出数据压缩
set mapreduce.output.fileoutputformat.compress=true;
–3、设置mapreduce最终数据输出压缩方式
set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;
–4、设置mapreduce最终数据输出压缩为块压缩
set mapreduce.output.fileoutputformat.compress.type=Lzo;

其他参数调优
1、有数据倾斜的时候进行负载均衡
set hive.groupby.skewindata=true;
2、向量化
hive.vectorized.execution.enabled :表示是否开启向量模式,默认值为 false。开启该配置,意味着从每次读取一条记录,变成每次读取一批数据。tez和spark引擎支持map和reduce端的向量模式。
3、 set hive.mapjoin.smalltable.filesize(Hive 0.8.1 之后):默认值 2500000(25MB) 如果大小表在进行表连接时,小表的数据量小于该默认值,则自动开启 MapJoin 优化。Hive 0.11 及以后的版本,可以使用。
4、在MR job中,默认是每执行一个task就启动一个JVM。如果task非常小而碎,那么JVM启动和关闭的耗时就会很长。可以通过调节参数mapred.job.reuse.jvm.num.tasks来重用。例如将这个参数设成5,那么就代表同一个MR job中顺序执行的5个task可以重复使用一个JVM,减少启动和关闭的开销。但它对不同MR job中的task无效。

总结:
1、尽量不要通过设置参数的方式进行优化,首先要看能否从业务上或者算法上减少数据和其他方式进行优化。

2、设置参数的话,要首先确定是Map、Reduce、Join哪个阶段的任务时间长,从而设置对应的参数。

3、在没有出现数据倾斜的情况下,如果通过设置Cpu参数(含Memory参数)和设置Instance个数两种方式都能调优的话,最好是先设置Instance个数。因为如果Cpu/Memory参数设置不合理,执行任务的机器满足不了参数的要求,要重新找机器的,这样反而会影响效率。如果执行日志中出现Dump,最好是Instance个数和Memory都增大一下。

4、Instance的个数设置,有个简单的方法是二分法。先设置个很大的,如果不能满足要求,那么就继续增大,如果满足了要求,就折半降低参数大小,最终找到一个合适的值。

5、默认的Reduce Instance的个数,与Map Instance个数是成一定比例关系的(一般是几分之几)。如果设置Reduce Instance参数的话,就会突破这个限制。默认的Join参数的个数一般是参加Join的任务的Instance个数之和。

5、Mr、Tez、Spark计算引擎对比

Hive引擎包括:默认MR、Tez、Spark

Tez
Tez是Apache开源的支持DAG作业的计算框架,它直接源于MapReduce框架,核心思想是将Map和Reduce两个操作进一步拆分,即Map被拆分成Input、Processor、Sort、Merge和Output, Reduce被拆分成Input、Shuffle、Sort、Merge、Processor和Output等,这样,这些分解后的元操作可以任意灵活组合,产生新的操作,这些操作经过一些控制程序组装后,可形成一个大的DAG作业

Spark
Spark是UC Berkeley AMP lab所开源的类Hadoop MapReduce的通用的并行计算框架,Spark基于map reduce算法实现的分布式计算,拥有Hadoop MapReduce所具有的优点;但不同于MapReduce的是,计算速度快,因为spark从磁盘中读取数据,把中间数据放到内存中,完成所有必须的分析处理,将结果写回集群。因此Spark能更好地适用于数据挖掘与机器学习等需要迭代的map reduce的算法。

Tez和Mapreduce区别
核心思想:MapReduce将一个算法抽象成Map和Reduce两个阶段进行处理;Tez将Map和Reduce两个操作进一步拆分,即Map被拆分成Input、Processor、Sort、Merge和Output, Reduce被拆分成Input、Shuffle、Sort、Merge、Processor和Output等依赖DAG:Mapreduce没有DAG一说,Tez将map和reduce阶段拆分成多个阶段,分解后的元操作可以任意灵活组合,产生新的操作,这些操作经过一些控制程序组装后,可形成一个大的DAG作业落地磁盘:MapReduce会有多次落地磁盘;Tez可以将多个有依赖的作业转换为一个作业,这样只需写一次HDFS,且中间节点较少,从而大大提升作业的计算性能。

Tez和Spark区别
1、spark属于内存计算,支持多种运行模式,可以跑在standalone,yarn上;而tez只能跑在yarn上;虽然spark与yarn兼容,但是spark不适合和其他yarn应用跑在一起。
2、tez能够及时的释放资源,重用container,节省调度时间,对内存的资源要求率不高; 而spark如果存在迭代计算时,container一直占用资源;
总结: tez与spark两者并不矛盾,不存在冲突,在实际生产中,如果数据需要快速处理而且资源充足,则可以选择spark;如果资源是瓶颈,则可以使用tez;

5.1、Mr和Spark的shuffle过程区别

本质上都是把Map端数据分类处理后交由Reduce计算处理的过程,但它们有一些不同之处:

1、数据传输方式:在MR Shuffle中,数据会通过磁盘进行中间结果的传输。Map阶段的输出会被写入磁盘,Reducer会从磁盘读取中间结果并进行合并。而Spark Shuffle使用了内存和磁盘的混合传输方式。默认情况下,Spark会尝试尽可能多地将数据保留在内存中,以提高性能。只有当内存不足时,才会将数据溢写到磁盘。

2、数据合并方式:在MR Shuffle中,Reducer会从磁盘读取多个Map输出,并将它们按照键进行排序和合并。这个过程中会使用外部排序算法,需要大量的磁盘 I/O 操作。而Spark Shuffle使用了更高效的排序和合并算法。它将数据按照分区存储在内存中,并使用排序和合并算法对内存数据进行操作,从而减少了磁盘 I/O 操作的数量。这使得Spark Shuffle通常比MR Shuffle具有更好的性能。

3、内存管理:Spark Shuffle具有更灵活的内存管理机制。Spark通过调整缓存的数据大小和使用现有内存大小的比例,以及通过内存溢写到磁盘,动态调整数据在内存和磁盘之间的分配。这使得Spark Shuffle能够更好地适应不同的资源和数据规模,提供更高的性能。

总体而言,Spark Shuffle相对于MR Shuffle具有更高的性能和更灵活的内存管理。通过内存和磁盘的混合传输、高效的排序和合并算法以及动态的内存管理策略,Spark能够在处理大规模数据时提供更好的性能和可伸缩性。

5.2、Spark中RDD和DataFrame的区别

RDD(Resilient Distributed Dataset)和DataFrame是Spark中两种不同的数据抽象和处理方式,都是分布式的数据集,它们有以下几个主要区别:

1、数据模型:
1)RDD是Spark最早引入的数据抽象,可以存储任意类型的对象。RDD没有特定的数据模型,每个RDD都是由一组分区(partitions)组成,每个分区中都包含一些数据记录。
2)DataFrame是Spark引入的基于结构化数据的概念,以类似于关系型数据库表的形式来组织和处理数据。具有明确的结构,每列都有特定的名称和数据类型,类似于表的列。

2、类型检查和优化:
1)RDD是动态的、不确定的数据集合,没有完整的类型信息,所有的操作都是使用通用的函数式API进行。由于缺乏类型信息,RDD的错误只有在运行时才能检测到。同时,RDD的处理逻辑也无法进行优化。
2)DataFrame在构建时会进行结构推断(schema inference),根据数据的类型推断出列的名称和数据类型,从而具有静态的结构信息。由于有明确的结构信息,Spark可以在编译时对DataFrame的操作进行类型检查和优化。

3、API和语法:
1)RDD的操作使用函数式编程的API,需要显式地定义和编写转换和行动操作的逻辑。RDD提供了更底层的抽象,可以进行更灵活的操作,但编码复杂度较高。
2)DataFrame的操作使用更高级、更可读性强的SQL-like API,包括类似SQL的查询,可以链式调用操作,更易于使用和理解。DataFrame的API提供了许多内置的优化和优化器,可以自动选择合适的执行计划。

4、Catalyst优化器:
1)DataFrame使用了Spark的Catalyst优化器,该优化器可以在执行计划生成过程中进行优化,例如推测性执行、谓词下推等,以改善查询性能。Catalyst还支持优化器规则和逻辑优化,以提高查询效率。
2)RDD不具备Catalyst优化器的优化能力,RDD的操作是直接按照编写的代码进行执行。

总之,RDD是Spark最原始的数据抽象,适用于通用的、灵活的分布式数据处理。DataFrame是基于结构化数据的更高级别的数据抽象,具有结构信息、类型检查和优化能力,使得数据处理更易用和高效。在性能上,DataFrame在许多情况下可以优于RDD,并且更适用于数据分析和SQL处理等场景。

6、Hadoop的心跳机制

Hadoop集群中各个组件之间保持通信和状态同步的机制。在Hadoop集群中,有主节点(如NameNode)和多个从节点(如DataNode),心跳机制主要用于从节点向主节点发送心跳信号以示活着,并且用于主节点向从节点发送指令或请求。具体来说,Hadoop的心跳机制如下:
  1、Hadoop 中使用的是主从架构 Master/Slave,Master 中有 NameNode、ResourceManage,Salve 中有 DataNode、NodeManage;
  2、Master 启动的时候,会启动一个 IPC 服务,等待 Slave 的链接;
  3、Slave 启动的时候,会主动的链接 Master 的 ipc server 服务;
  4、Slave 会每隔 3 秒(默认值)访问一次 Master 的 ipc server 服务;
  5、将这种 每隔 3 秒访问一次的机制称之为心跳机制;
  6、心跳的间隔时长可以通过 dfs.heartbeat.interval 的参数进行设置;
  7、NameNode 通过心跳得知 DataNode 的状态;ResourceManager 通过心跳得知 NodeManager 的状态;
  8、如果 Master 长时间没有收到 Slave 的心跳,则认为该 Slave 节点挂掉了;
  9、NameNode 感知 DataNode 掉线死亡的时长计算公式:2 倍的尝试重新连接时间 + 10 倍的心跳时间;默认值 2 倍的 5 分钟 + 10 倍的 3 秒 = 10 分钟 30 秒;

数据节点(DataNode)心跳:
数据节点向主节点发送心跳信号,以通知主节点它们的存在和可用性。
心跳信息中包含数据节点的状态、存储容量、块信息等。
主节点通过接收数据节点的心跳信息,来监控数据节点的健康状态。

名称节点(NameNode)心跳:
名称节点是Hadoop文件系统的主节点,负责管理文件系统的元数据。
名称节点定期向数据节点发送心跳信号,以检查数据节点的健康状态。
心跳信息中包含数据节点的状态、存储容量、块信息等。

任务节点(TaskTracker)心跳:
任务节点是Hadoop任务调度的从节点,负责执行MapReduce任务。
任务节点周期性地向资源管理器(ResourceManager)发送心跳信号。
心跳信息中包含任务节点的状态、可用资源等。
资源管理器通过接收任务节点的心跳信息,来监控任务节点的健康状态和可用资源。

资源管理器(ResourceManager)心跳:
资源管理器是Hadoop集群资源的主节点,负责全局资源的管理和分配。
资源管理器会周期性地向任务节点发送心跳信号,以检查任务节点的健康状态。
心跳信息中包含任务节点的状态、可用资源等。
心跳机制有助于实现集群中各个组件之间的实时通信和状态同步。主节点通过接收从节点的心跳信号,可以了解集群中各节点的状态,并做出相应的处理,如重新分配任务、剔除故障节点等。同时,从节点也能通过心跳机制获取主节点的指令或请求,如块的复制指令等。

通过心跳机制,Hadoop集群能够实现分布式系统的高可用性和容错性,保障集群的稳定和正常运行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

大数据面试知识点梳理 的相关文章

随机推荐

  • C++Primer第五版课后习题答案目录

    本帖用来记录我在看C Primer第五版时课后习题的代码以及书中一些问题的思考 仅供参考 水平有限 如有错误之处 请大家不吝指教 谢谢 目录 第一章 开始 第二章 变量和基本类型 第三章 字符串 向量和数组 第四章 表达式 第五章 语句
  • Linux 命令之 - scp(从远端机器拉取数据)

    scp是secure copy的简写 用于在Linux下进行远程拷贝文件的命令 和它类似的命令有cp 不过cp只是在本机进行拷贝不能跨服务器 而且scp传输是加密的 命令格式 scp 参数 原路径 目标路径 从本地服务器复制到远程服务器 需
  • 网易滑块验证

    之前在写瑞数专题一时就想发一篇关于网易滑块验证的案例 奈何现在的大佬好像比较喜欢瑞数 不管咋样 还是来水一篇网易滑块验证相关的文章 首先是获取图片的部分参数 fp cb callback这三个都是加密而来 图片验证这里的acToken可以不
  • 聊聊分布式任务调度系统

    我看过那么多所谓的教程 大部分都是教 如何使用工具 的 没有多少是教 如何制作工具 的 能教 如何仿制工具 的都已经是凤毛麟角 中国 软件行业 缺的是真正可以 制作工具 的程序员 而绝对不缺那些 使用工具 的程序员 这个业界最不需要的就是
  • 二、三层转发原理(多例详解,图文相结合说明ping过程)

    首先要了解 源主机在发起通信之前 会将自己的IP与目的主机的IP进行比较 如果两者位于同一网段 用网络掩码计算后具有相同的网络号 那么源主机发送arp请求广播报 请求目的主机的mac地址 在收到目的主机的ARP应答后获得对方的物理层 MAC
  • mysql 错误代码1171

    在创建主键id的时候没有取消上图的允许空值 导致报错1171 Error All part of primary key must be not null when installing flag module 转载于 https www
  • 一位股市天才的肺腑独白:一直只用MACD指标来炒股

    在股市投资中 MACD指标作为一种技术分析的手段 得到了投资者的认知 但如何使用MACD指标 才能使投资收益达到最佳境界 却是知者甚微 在股市操作中 MACD指标在保护投资者利益方面 远超过它发现投资机会的功效 如何巧用MACD指标 在股海
  • linux 重启服务器命令

    Linux有如下的关机和重启命令 shutdown reboot halt poweroff 那么它们有什么区别呢 shutdown 建议使用的命令 shutdown是最常用也是最安全的关机和重启命令 它会在关机之前调用fsck检查磁盘 其
  • 计算机系统基础摘记——程序的链接

    目录 1 初探链接 1 1 可执行文件的生成过程 1 2 链接器的由来 1 3 概述链接器的关键作用 1 4 链接带来的好处 2 目标文件 2 1 一些基本概念 2 2 可重定位文件 2 2 1 可重定位文件的格式 2 2 2 ELF头的格
  • 基础算法题——Harder Gcd Problem(数论、思维)

    题目 题目链接 给定一个 n 将 2 n 内的数进行一对一匹配 每个数仅能利用一次 假设 a 与 b 匹配 则 gcd a b 1 现求 2 n 内最大匹配数量 并输出匹配数对 输入 T代表输入组数 下面T行 每一行一个数字n 输出 输出最
  • 数据结构之邻接表及广度优先遍历

    一 邻接表的概念 邻接表是图的一种最主要存储结构 相当于图的压缩存储 用来描述图上的每一个点 图的邻接表存储方法跟树的孩子链表示法相类似 是一种顺序分配和链式分配相结合的存储结构 如这个表头结点所对应的顶点存在相邻顶点 则把相邻顶点依次存放
  • JavaWeb --- CSS

    一 CSS技术介绍 CSS是 层样式表单 是用于 增强 控制网页样式并允许将样式信息与网页内容分离的一种标记性语言 二 CSS语法规则 三 CSS和HTML结合方式 第一种 在标签的style属性上设置key value value 修改标
  • 简单易学的机器学习算法——SVD奇异值分解

    一 SVD奇异值分解的定义 假设是一个的矩阵 如果存在一个分解 其中为的酉矩阵 为的半正定对角矩阵 为的共轭转置矩阵 且为的酉矩阵 这样的分解称为的奇异值分解 对角线上的元素称为奇异值 称为左奇异矩阵 称为右奇异矩阵 二 SVD奇异值分解与
  • 【加载静态资源很慢】解决浏览器加载静态资源阻塞

    开门见山讲方法 增加浏览器的最大并发连接数 避免静态资源的加载请求排队而被其他请求阻塞 仅测试火狐浏览器可用 Chrome据我所知不支持此项配置 IE浏览器需要通过修改组策略 未测试 正文 存在问题 今天调试网页时 网页加载缓慢 一方面主要
  • es基本配置文件详解

    基本概念 近实时 Near Realtime NRT Elasticsearch是一个接近实时的搜索平台 这意味着从索引文档的时间到可搜索的时间之间存在轻微的延迟 通常为一秒 集群 Cluster 集群是一个或多个节点 服务器 的集合 它们
  • FPGA篇(十二)仿真中 `timesclae的用法

    timescale 1ns 1ps 小实验 timescale 1ns 1ps 前面是刻度 小数点之前 后面是精度 小数点之后 一旦超过了精度 就会四舍五入 modelSim仿真 仿真代码如下所示 timescale 1ns 1ps reg
  • 关于Failed to load plugin ‘vue‘ declared in ‘.eslintrc.js‘: createRequire is not a function报错处理

    今天从git上拉了项目代码 install之后就run dev准备跑项目 突然报错TypeError Failed to load plugin vue declared in eslintrc js createRequire is no
  • 免费HTTP代理怎么样

    现在是信息时代 很多互联网场景比如爬虫信息采集 电商效果补量 网上推广等等 都离不开HTTP代理IP 而很多人第一个想到的就是免费HTTP代理 什么是代理服务器 代理服务器是介于浏览器和Web服务器之间的一台服务器 当你通过代理服务器上网浏
  • 提高机器学习模型性能的五个关键方法

    如何提高机器学习模型性能 可从五个关键方面入手 1 数据预处理 2 特征工程 3 机器学习算法 4 模型集成与融合 5 数据增强 以下是各个方面的具体分析和方法 说明 1 这里主要是各个关键方法的知识汇总梳理 便于集中学习 具体的实际应用内
  • 大数据面试知识点梳理

    1 hadoop是什么 Hadoop是一个由Apache基金会所开发的分布式系统基础架构 主要解决海量数据存储与计算的问题 其中主要包括HDFS MapReduce和Yarn框架 2 HDFS HDFS四大机制 心跳机制 安全机制 机架策略