大数据总结

大数据面试题

Hadoop 常见面试题(120)

1. mr 工作原理

mr 将得到的split 分配对应的 task,每个任务处理相对应的 split,将 split 以 line 方式读取每一行数据,将数据依次读取到100M(maprdeuce.task.io.sort.mb)的环形缓冲区读取过程中一旦到达阈值(mapreduce.map.sort.spill.percent)80M进行溢写操作,spiller线程溢写到磁盘(mapreduce.cluster.local.dir)目录中,期间会进行kv分区(分区数由reduce数来决定)默认使用hashpartition,再将分区中数据进行key的排序(默认排序规则是字典和升序),如果设置了setCombinerClass 则会对每个分区中的数据进行 combiner 操作,如果设置了output.compress压缩格式会对溢写的数据进行压缩,最后merge根据分区规则将数据归并到同一个文件中等待reduce的拉取,nodemanger将启动一个mapreduce_shuffle服务将数据以http方式拉取到reduce端,reduce处理阶段当达到阈值(默认0.66)或map输出数的阈值(默认100)会进行merge(同一分区的一组数据会先进行归并)|sort(将归并好的数据进行排序)|group(判断迭代器中的元素是否可以迭代),处理完成mr将同一个分区内的数据,在hdfs中以文件形式体现出来,几个分区就会创建几个文件。

其中reduce端的merge达到阈值会触发,sort则是维持其map阶段顺序,而group是设置( setGroupingComparatorClass)后才会触发。

有效的理解mr工作流程可大大提升程序运行效率,其中 mr 的 shuffle 也被称为奇迹开始的地方

2. split 机制

spilit 是在mr 处理的map端之前产生的概念,split切片大小,默认等于block*1.1,在FileInputFormat中计算切片大小的逻辑:

blocksize:默认是 128M,可通过 dfs.blocksize 修改

minSize:默认是 1,可通过 mapreduce.input.fileinputformat.split.minsize 修改

maxsize:默认是 Long.MaxValue,可通过 mapreduce.input.fileinputformat.split.maxsize 修改

Hadoop FileInputFormat 源码:

3. namenode,datanode,secondaryNameNode分别是干什么的?

namenode,在基于主从架构的hdfs文件系统中是主节点,其主要职责就是对hdfs中的文件的元信息,副本数,文件目录树,block 数据节点信息;
datanode,它是从节点也是数据节点,基于本地磁盘存储 block(文件的形式),有相关数据块的长度、效验和、时间戳,与namnode保持心跳,汇报 block 状态。
secondaryNameNode,检查点节点,namenode 日志高可用的关键,其主要作用就是将namenode的元数据日志信息合并后备份,防止元数据丢失。
元信息:是数据文件的block大小,文件副本存储位置,副本数量,block 数量,主要体现在edits文件和fsimage文件。
副本数:hdfs 中同一个文件在多个节点中所存储的总数量,也是实现持久化和保证安全性的关键。
文件目录树:hdfs提供了一个可以维护的文件目录,该文件目录下存储着有关所有hdfs的文件。
block 数据节点信息:如a文件在01和02节点中存储,该信息称为数据节点信息。
edits:记录 client 执行创建,移动,修改文件的信息,同时体现了 HDFS 的最新的状态(二进制文件)。
它分布在磁盘上的多个文件,名称由前缀 edits 及后缀组成.后缀值是该文件包含的事务 ID,同一时刻只有一个文件处于可读写状态.为避免数据丢失,事务完成后 client 端在执行成功前,文件会进行更新和同步,当 NN 向多个目录写数据时,只有在所有操作更新并同步到每个副本之后执行才成功。
fsimage:记录的是数据块的位置信息、数据块的冗余信息(二进制文件)
由于 edits 文件记录了最新状态信息,并且随着操作越多,edits 文件就会越大,把 edits 文件中最新的信息写到 fsimage 文件中就解决了 edits 文件数量多不方便管理的情况。
没有体现 HDFS 的最新状态。
每个 fsimage 文件都是文件系统元数据的一个完整的永久性的检查点。
为什么引入 secondaryNameNode?
由于只有在重启时 fsimage 和 edits 才会进行合并,得到一个新的 fsimage 文件,但是在实际生产环境中很少会重启集群,NN 的重启需要花费很长时间,因为会有很多改动需要合并到 fsimage 文件上,如果 NN 挂掉,fsimage 文件没有更新内容,从而丢失很多改动。
但 editlog 日志大小会随着时间变的越来越大,导致系统重启,根据日志恢复元数据的时间会越来越长;
为了避免这种情况,引入检查点机制checkpoint,命名空间镜像 fsimage 就是 HDFS 元数据的持久性检查点,即将内存中的元数据落磁盘生成的文件;

4. mr on yarn 工作原理

1、向client端提交MapReduce job.

2、随后yarn的ResourceManager进行资源的分配.

3、由NodeManager进行加载与监控containers.

4、通过applicationMaster与ResourceManager进行资源的申请及状态的交互,由NodeManagers进行MapReduce运行时job的管理.

5、通过hdfs进行job配置文件、jar包的各节点分发。

5. fsimage 和 edits 是干什么的?为什么要使用?

edits:记录 client 执行创建,移动,修改文件的信息,同时体现了 HDFS 的最新的状态(二进制文件)。

它分布在磁盘上的多个文件,名称由前缀 edits 及后缀组成.后缀值是该文件包含的事务
ID,同一时刻只有一个文件处于可读写状态.为避免数据丢失,事务完成后 client 端在执行成功前,文件会进行更新和同步,当 NN
向多个目录写数据时,只有在所有操作更新并同步到每个副本之后执行才成功。

fsimage:记录的是数据块的位置信息、数据块的冗余信息(二进制文件)

由于 edits 文件记录了最新状态信息,并且随着操作越多,edits 文件就会越大,把 edits 文件中最新的信息写到 fsimage
文件中就解决了 edits 文件数量多不方便管理的情况。

没有体现 HDFS 的最新状态。

每个 fsimage 文件都是文件系统元数据的一个完整的永久性的检查点。

为什么使用?

NN 使用了 FsImage+EditLog 整合的方案;

滚动将增量的 EditLog 更新到 FsImage,以保证更近时点的 FsImage 和更小的 EditLog 体积

6. hdfs 工作原理

一般就是读写的工作流程,因为hdfs 主要还是对文件存储与读写。

读流程

client端创建一个代理对象与namenode进行rpc通信,拿到namenode对象后请求获取文件的元信息,namenode效验无误后将元信息返回,client获取到元信息之后根据元信息读取相应datanode的block块,将block合并成一个文件进行返回。

写流程

client端创建一个代理对象与namenode进行rpc通信,拿到namenode对象后请求创建文件的元信息,namenode触发副本放置策略,返回元数据信息,client和datanode建立piepline连接,client将packet放入一个队列中,并向第一个datanode发送packet这一过程中上游节点同时发送下一个packet,当
block 传输完成,DN 们各自向 NN 汇报,同时 Client 继续传输下一个 block所以,Client 的传输和 block
的汇报也是并行的

7. block 副本放置策略

1.x

第一个副本:放置在上传文件的 DataNode;如果时集群外提交,则随机挑选一台磁盘不太满,CPU 不太忙的节点。
第二个副本:放置在于第一个副本不同的机架的节点上。 第三个副本:与第一个副本相同机架的节点。 更多副本:随机节点
可能产生的问题是前两个副本在同一机架当机架出现问题时会丢失两个副本

2.x

第一个副本:放置在上传文件的 DataNode;如果时集群外提交,则随机挑选一台磁盘不太满,CPU 不太忙的节点。
第二个副本:放置在于第一个副本不同的机架的节点上。 第三个副本:与第二个副本相同机架的节点。 更多副本:随机节点

谈谈Hadoop序列化和反序列化及自定义bean对象实现序列化?

1)序列化就是把内存中的对象,转换成字节序列(或其他数据传输协议)以便于存储(持久化)和网络传输。

2)反序列化就是将收到字节序列(或其他数据传输协议)或者是硬盘的持久化数据,转换成内存中的对象。

为什么要序列化

一般来说,“活的”对象只生存在内存里,关机断电就没有了。而且“活的”对象只能由本地的进程使用,不能被发送到网络上的另外一台计算机。然而序列化可以存储“活的”对象,可以将“活的”对象发送到远程计算机

为什么不用Java序列化

Java的序列化是一个重量级序列化框架(Serializable),一个对象被序列化后,会附带很多额外的信息(各种校验信息,header,继承体系等),不便于在网络中高效传输。所以,hadoop自己开发了一套序列化机制(Writable),精简、高效。

描述mapReduce有几种排序及排序发生的阶段(☆☆☆☆☆)

1)部分排序:MapReduce根据输入记录的键对数据集排序。保证输出的每个文件内部排序。

2)全排序:如何用Hadoop产生一个全局排序的文件?最简单的方法是使用一个分区。但该方法在处理大型文件时效率极低,因为一台机器必须处理所有输出文件,从而完全丧失了MapReduce所提供的并行架构。

替代方案:首先创建一系列排好序的文件;其次,串联这些文件;最后,生成一个全局排序的文件。主要思路是使用一个分区来描述输出的全局排序。例如:可以为待分析文件创建3个分区,在第一分区中,记录的单词首字母a-g,第二分区记录单词首字母h-n, 第三分区记录单词首字母o-z。

3)辅助排序(GroupingComparator分组):Mapreduce框架在记录到达reducer之前按键对记录排序,但键所对应的值并没有被排序。甚至在不同的执行轮次中,这些值的排序也不固定,因为它们来自不同的map任务且这些map任务在不同轮次中完成时间各不相同。一般来说,大多数MapReduce程序会避免让reduce函数依赖于值的排序。但是,有时也需要通过特定的方法对键进行排序和分组等以实现对值的排序。

4)二次排序:在自定义排序过程中,如果compareTo中的判断条件为两个即为二次排序。

描述mapReduce中shuffle阶段的工作流程,如何优化shuffle阶段

map 端的shuffle 过程
写入磁盘
map 端会先将输出写入到内存缓冲区,当内存缓冲区到达指定的阈值时,一个后台线程就开始将缓冲区的内容spill 到磁盘。

分区&排序
在写入磁盘之前,线程首先根据数据最终要到达的reducer 将数据划分为相应的分区。在每个分区中,后台线程按键进行内存中排序。(分区的目的是将数据划分到不同的Reducer 上去,以期望达到负载均衡)

合并阶段
每个map 任务可能产生多个spill 文件,在任务完成之前,spill 文件会被合并为一个已分区已排序的输出文件。

reduce 端的shuffle 过程
复制阶段
每个reduce 任务需要若干个map 任务的输出作为输入,每个map 任务的完成时间可能不同,因此在每个任务完成时,reduce 任务就开始复制其输出。

这就是reduce 任务的复制阶段。reduce 任务有少量的复制线程,因此能够并行取得map 输出。

合并阶段
复制完所有map 输出后,reduce 任务进入合并阶段。这个阶段将合并map 输出,并维持其顺序排序。最后将合并结果数据直接输入reduce 函数。

Hive常见面试题(121)

1. 简述Hive工作原理

1、执行查询:Hive接口,命令行或 web UI发送查询驱动程序

2、get Plan:驱动程序查询编译器

3、词法分析/语法分析

4、语义分析

5、逻辑计划产生

6、逻辑计划优化

7、物理计划生成

8、物理计划优化

9、物理计划执行

10、查询结果返回

2. hive 内部表和外部表区别

创建表时:创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径, 不对数据的位置做任何改变。

删除表时:在删除表的时候,内部表的元数据和数据会被一起删除,
而外部表只删除元数据,不删除数据。这样外部表相对来说更加安全些,数据组织也更加灵活,方便共享源数据。

3. 分区和分桶的区别 ☆☆☆☆

3.1 分区

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

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

3.2 分表

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

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

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

总结:分区就是在hdfs上分目录(文件夹),分桶就是分文件。

4. 将数据直接上传到分区目录(hdfs)上,让分区表和数据产生关联有哪些方式

方案一:上传数据后修复表 dfs -mkdir -p 分区目录 dfs -put 分区目录 msck repair table 表名
方案二:上传数据后添加分区 dfs -mkdir -p 分区目录 dfs -put 分区目录 alter table 表名 add
partition();

提示:这里我们如果直接将新的分区文件上传到hdfs上,因为hive没有对应的元数据所以是无法查询到数据的,所以我们要进行表修复或者添加分区。

5. 桶表是否可以通过直接load将数据导入?

不可以,因为load数据的话hdfs下只会有一个文件无法完成分桶的效果,分桶和mapredue中的分区是一样的道理,所以我们要借助中间表导入数据。

6. order by,sort by,distribute by,cluster by的区别?

  1. order by会对所给的全部数据进行全局排序 ,不管来多少数据,都只启动一个reducer来处理 。

  2. sort by是局部排序 ,sort by会根据数据量的大小启动一到多个reducer来干活,并且,它会在进入reduce之前为每个reducer都产生一个排序文件 。

  3. distribute by 控制map结果的分发,它会将具有相同字段的map输出分发到一个reduce节点上做处理 。

  4. cluster by 可以理解为一个特殊的distribute by和sort by的结合,当distribute by和sort
    by后面所跟的列名相同时,就等同于直接使用cluster by 跟上该列名。但是被cluster
    by指定的列最终的排序结果只能是降序,而且无法指定asc和desc。

7. 聚合函数是否可以写在order by后面,为什么?

不可以。

原因:执行顺序!!!order by的执行顺序在select之后,所以需使用重新定义的列名进行排序。

8. 导致数据倾斜的原因有哪些,有什么解决的方案?

什么是数据倾斜?

数据倾斜就是数据的分布不平衡,某些地方特别多,某些地方又特别少,导致的在处理数据的时候,有些很快就处理完了,而有些又迟迟未能处理完,导致整体任务最终迟迟无法完成,这种现象就是数据倾斜。

针对mapreduce的过程来说就是,有多个reduce,其中有一个或者若干个reduce要处理的数据量特别大,而其他的reduce处理的数据量则比较小,那么这些数据量小的reduce很快就可以完成,而数据量大的则需要很多时间,导致整个任务一直在等它而迟迟无法完成。
跑mr任务时常见的reduce的进度总是卡在99%,这种现象很大可能就是数据倾斜造成的。

造成数据倾斜的原因

比如某些业务数据作为key的字段本就很集中,那么结果肯定会导致数据倾斜啊。
还有其他的一些原因,但是,根本原因还是key的分布不均匀,而其他的原因就是会造成key不均匀,进而导致数据倾斜的后果,所以说根本原因是key的分布不均匀。

既然有数据倾斜这种现象,就必须要有数据倾斜对应的处理方案啊。
简单地说数据倾斜这种现象导致的任务迟迟不能完成,耗费了太多时间,极大地影响了性能,所以我们数据倾斜的解决方案设计思路就是往如何提高性能,即如何缩短任务的处理时间这方面考虑的,而要提高性能,就要让key分布相对均衡,所以我们的终极目标就是考虑如何预处理数据才能够使得它的key分布均匀。

你是如何发现Hive数据倾斜?

通过 yarn 监控平台的 task 信息查看到有个别的 task 执行时间过于缓慢,甚至还会挂掉。

解决办法

1 合理设置Map数 1) 通常情况下,作业会通过input的目录产生一个或者多个map任务。 2)
是不是map数越多越好?答案是否定的。如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。
是不是保证每个map处理接近128m的文件块,就高枕无忧了?答案也是不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。

针对上面的问题2和3,我们需要采取两种方式来解决:即减少map数和增加map数;
2 小文件合并 在map执行前合并小文件,减少map数:

CombineHiveInputFormat 具有对小文件进行合并的功能(系统默认的格式)

3 复杂文件增加Map数
当input的文件都很大,任务逻辑复杂,map执行非常慢的时候,可以考虑增加Map数,来使得每个map处理的数据量减少,从而提高任务的执行效率。

增加map的方法为

根据 computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))公式
调整maxSize最大值。让maxSize最大值低于blocksize就可以增加map的个数。
4 合理设置Reduce数
1、调整reduce个数方法一
1)每个Reduce处理的数据量默认是256MB
2)每个任务最大的reduce数,默认为1009
3、reduce个数并不是越多越好
过多的启动和初始化reduce也会消耗时间和资源;
同时过多的reduce会生成很多个文件,也有可能出现小文件问题
总的来说就是,数据倾斜的根源是key分布不均匀,所以应对方案要么是从源头解决(不让数据分区,直接在map端搞定),要么就是在分区时将这些集中却无效的key过滤(清洗)掉,或者是想办法将这些key打乱(给key加上标签),让它们进入到不同的reduce中。

9. Hive的四种排序

order by
order by 会对输入做全局排序,因此只有一个reducer(多个reducer无法保证全局有序)
只有一个reducer,会导致当输入规模比较大时,需要较长的时间。
set hive.mapred.mode=nonstrict; (default value / 默认值)
set hive.mapred.mode=strict;
order by 和数据库中的order by功能一致按照某一项&几项排序输出。
与数据库中order by的区别在于hive.mapred.mode = strict模式下 必须指定limit否则执行会报错
原因:在order by状态下所有的数据都会到一台服务器进行reduce操作也就是只有一个reduce, 如果在数据量大的情况下会出现无果的情况,如果进行limit n,那只有n * map
number 条记录而已。只有一个reduce也可以出来里过来

sort by
sort by不是全局排序,其在数据进入reducer前完成排序
因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1,则sort by只保证每个reducer 的输出有序,不保证全局有序。sort by 不受hive.mapred.mode是否为strict,nostrict的影响。
sort by的数据只能保证在同一个reduce中的数据可以按指定字段排序。
使用sort by你可以指定执行的reduce个数(set mapred.reduce.tasks=),对输出的 数据在执行归并排序,即可以得到全部结果。
注意:可以用limit子句大大减少数据量。使用limit n后,传输到reduce端(单机)的数据记录就 减少到n*(map个数)。否则由于数据过大可能出不了结果。

distribute by
按照指定的字段对数据进行划分到不同的输出reduce / 文件中。
insert overwrite local directory ‘/home/hadoop/out’ select * from test order by name distribute by length(name);此方法会根据name的长度划分到不同的reduce中,最终输出到不同的文件中。
length 是内建函数,也可以指定其他的函数或这使用自定义函数。

Cluster By
cluster by 除了具有 distribute by 的功能外还兼具 sort by 的功能。但是排序只能是倒序排序,不能指定排序规则为asc 或者desc。

10. Hive的分区分桶

我们发现其实桶的概念就是MapReduce的分区的概念,两者完全相同。物理上每个桶就是目录里的一个文件,一个作业产生的桶(输出文件)数量和reduce任务个数相同。

而分区表的概念,则是新的概念。分区代表了数据的仓库,也就是文件夹目录。每个文件夹下面可以放不同的数据文件。通过文件夹可以查询里面存放的文件。但文件夹本身和数据

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值