大数据—— Hadoop 常见面试题整理

Posted Vicky_Tang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大数据—— Hadoop 常见面试题整理相关的知识,希望对你有一定的参考价值。

目录

1. 大数据的特点(4V特征)

2. 谈谈 Hadoop 的优缺点

3. 为什么 HDFS 不适合存小文件

4. Hadoop 的核心组件有哪些,并说明下功能

5. Hadoop 与关系型数据库对比

6. 如果集群中 DataNode 出现错误(比如 DataNode 进程死亡或者网络故障造成无法与 NameNode 通信),集群能否立即将宕机的DataNode下线?另外DataNode 下线后,集群将进行什么工作?

7. 简单说明下 HDFS 中,NameNode ,SecondaryNameNode 和 DataNode 的作用

8. 简单描述一下 dfs-start.sh 的启动流程(或者 NameNode 的启动流程)

9. 什么情况下集群会进入安全模式

10. HDFS 的读写执行流程

11. HDFS 的可靠性策略有哪些

12. 如果一个 DataNode 宕机了,如何做恢复

13. MapReduce 的执行流程

14. Yarn 的 Job 提交流程

15. Hadoop 中数据块(Block)大小如何确定,现有一个文件大小为260M,Block大小设定为128MB,在进行 split 操作时,会生成几个 Block

16. Block 大小设置成多少合适

17. MapReduce 中有哪些关键类

18. Mapper 中 setup 方法是干嘛的

19. Hadoop Shuffle 原理

20. MapReduce 的调优

21. Hadoop 中支持的存储格式和压缩算法


1. 大数据的特点(4V特征)

  • Volume(大数据量):90% 的数据是过去两年产生
  • Velocity(速度快):数据增长速度快,时效性高
  • Variety(多样化):数据种类和来源多样化 结构化数据、半结构化数据、非结构化数据
  • Value(价值密度低):需挖掘获取数据价值

2. 谈谈 Hadoop 的优缺点

优点:

  • 高扩展性:在集群间分配任务数据,可方便的扩展数以千计的节点
  • 高可靠性:Hadoop底层维护多个数据副本
  • 高容错性:Hadoop框架能够自动将失败的任务重新分配
  • 低成本:Hadoop架构允许部署在廉价的机器上
  • 灵活,可存储任意类型数据
  • 开源,社区活跃

缺点:

  • Hadoop不适用于低延迟数据访问
  • Hadoop不能高效存储大量小文件
  • Hadoop不支持多用户写入并任意修改文件:一个文件只能有一个写者,仅支持append

3. 为什么 HDFS 不适合存小文件

HDFS 文件存储是以 Block 进行存储的(Hadoop 2.x 以后 Block 大小默认为128M),而 Block 元数据大小大概在 150 字节左右,Block 的元数据会在 NameNode 启动时加载到内存,也就意味着一个小文件就要占用 NameNode 150 字节内存,如果小文件过多,NameNode 内存很有可能被消耗殆尽,但整个集群存储数据的量却很小,失去了HDFS的意义,同时也会影响 NameNode 的寻址时间,导致寻址时间过长

4. Hadoop 的核心组件有哪些,并说明下功能

HDFS:分布式文件系统,解决分布式存储

MapReduce:分布式计算框架

YARN:分布式资源管理系统,在 Hadoop 2.x 中引入

Common:支持所有其他模块的公共工具程序

5. Hadoop 与关系型数据库对比

6. 如果集群中 DataNode 出现错误(比如 DataNode 进程死亡或者网络故障造成无法与 NameNode 通信),集群能否立即将宕机的DataNode下线?另外DataNode 下线后,集群将进行什么工作?

(1)不能立即下线,NameNode不会立即把该节点判定死亡,HDFS 默认的超时时长为10分30秒,如果定义timeout为超时时长,则超时时长的计算公式为:timeout = 2 * heartbeat.recheck.interval + 10 * dfs.heartbeat.interval,默认的heartbeat.recheck.interval为5分钟,dfs.heartbeat.interval默认为3秒

(2)DateNode 下线后,集群将复制下线的 DataNode 管理的块,在其他 DataNode 上做备份

7. 简单说明下 HDFS 中,NameNode ,SecondaryNameNode 和 DataNode 的作用

NameNode:

  • master 的角色,是 Hadoop 集群的管理者,也被称为 HDFS 的元数据节点。集群中只能有一个 Active 的 NameNode 对外提供服务 
  • 管理着 HDFS 的名称空间(文件目录树)及数据块(Block)映射信息及副本信息
  • 负责对接客户端的读写请求 

SecondaryNameNode:

  • 负责镜像备份
  • 完成日志和镜像的定期合并,即合并 NameNode 的 edit logs 到 fsimage 文件中

DataNode:

  • worker的角色,负责具体的执行操作
  • 存储实际的数据块(Block)
  • 执行数据块的读/写操作

8. 简单描述一下 dfs-start.sh 的启动流程(或者 NameNode 的启动流程)

第一阶段:NameNode 启动

  • 第一次启动 NameNode 会执行格式化并创建 fsimage 和 edits 文件。如果不是第一次启动,则直接加载 fsimage 和 edits 到内存中
  • 客户端对元数据进行增删改的请求
  • NameNode 记录操作日志,更新滚动日志
  • NameNode 在内存总队数据进行增删改查

第二阶段:DataNode 启动

  • 在集群启动时向 NameNode 注册存活状态
  • 启动时立即执行汇报 Block 信息,之后每隔1小时汇报一次
  • 与 NameNode 建立 3秒一次的心跳机制,汇报当前健康状态和磁盘使用情况

第三阶段:SecondaryNameNode 启动

  • SecondaryNameNode 询问 NameNode 是否需要 checkpoint,直接带回 NameNode 是否需要 checkpoint 的结果
  • SecondaryNameNode 请求执行 checkpoint
  • 将 NameNode 滚动前的编辑日志和镜像文件拷贝至 SecondaryNameNode
  • SecondaryNameNode 加载编辑日志和镜像文件到内存中进行合并
  • 生成新的镜像文件 fsimage.chkpoint
  • 拷贝 fsimage.chkpoint 到 NameNode
  • NameNode 将fsimage.chkpoint 重新命名成fsimage

另外,在这3个阶段完成之前,集群处于安全模式

9. 什么情况下集群会进入安全模式

集群启动时:

由于 NameNode 在启动时加载的是所有块位置的映射信息,而非完整的块数据,所以需要各个 DataNode 向 NameNode 发送最新的块列表信息来验证块是否有效,在此期间 NameNode 的文件系统对于客户端来说是只读的 

Block异常损坏:

当 NameNode 发现集群中的 Block 丢失数量大于设定阈值时,NameNode 会进入安全模式,对低于阈值的 Block 在其他 DataNode 节点上做备份

在执行负载均衡操作时需要进入安全模式:

由于在做负载均衡操作时会对Block进行复制和删除操作,所以需要进入安全模式

10. HDFS 的读写执行流程

写数据执行流程

  • 客户端通过 Distributed FileSystem 模块向 NameNode 请求上传文件,NameNode 需要检查目标文件是否已存在,父目录是否存在
  • NameNode 返回是否可以上传,不能上传则会返回异常
  • 确认可以上传后,客户端请求第一个 Block 上传到哪几个 DataNode 服务器上
  • NameNode 返回3个 DataNode 节点,例如dn1、dn2、dn3
  • 客户端通过 FSDataOutputStream 模块请求 dn1 上传数据,dn1 收到请求会继续调用 dn2,然后dn2 调用 dn3,建立通信管道
  • dn1、dn2、dn3 逐级应答客户端
  • 客户端向 dn1 以 packet(64KB)为单位上传第一个 Block,dn1 收到一个 packet 就会传给 dn2,dn2 传给 dn3,dn1 每传一个 packet 会放入应答队列等待应答
  • 当第一个 Block 上传完之后,客户端会再次请求  NameNode 上传第二个 Block 服务,直至所有Block 都完成上传

读数据执行流程

  • 首先调用 FileSystem.open() 方法,获取到 DistributedFileSystem 实例
  • DistributedFileSystem 向 NameNode 发起 RPC(远程过程调用)请求获得文件的开始部分或者全部 Block 列表,对于每个返回的 Block,都包含 Block 所在的 DataNode 地址,这些 DataNode 会按照 Hadoop 定义的集群拓扑结构得出与客户端的距离,然后进行排序。如果客户端本身就是一个 DataNode 节点,那么会优先从本地读取文件
  • DistributedFileSystem 会向客户端返回一个支持文件定位的输入流对象 FSDataInputStream,用于客户端读取数据。FSDataInputStream 包含一个 DFSInputStream 对象,这个对象用来管理 DataNode 和 NameNode 之间的 I/O
  • 客户端调用 read() 方法,DFSInputSteam 就会找出离客户端最近的 DataNode 并连接 DataNode
  • DFSInputStream 对象中包含文件开始部分的数据块所在的 DataNode 地址,首先它会连接包含文件的第一个块最近的 DataNode。随后在数据流中重复调用 read() 函数,直到一个块全部读完为止。如果第一个块数据全部读完,就会关闭指向第一个块的 DataNode 连接,接着读取下一个块
  • 如果所有块都读完,就会关闭掉所有的流

11. HDFS 的可靠性策略有哪些

文件完整性:

  • 文件建立时,每个数据块都产生校验和,校验和保存在 .meta 文件内
  • 客户端获取数据时可以检查校验和是否相同,从而发现数据块是否损坏
  • 如果正在读取的数据块损坏,则可以继续读取其他副本,同时 NameNode 标记该数据块已经损坏,然后复制数据块达到预期的文件备份数
  • DataNode 在其文件创建后三周验证其checksum

网络或机器失效时:

  • 副本冗余
  • 机架感知策略(副本放置策略)
  • 心跳机制策略

NameNode 挂掉时:

  • 主备切换(体现了 Hadoop 集群的高可用)
  • 镜像文件和操作日志磁盘存储
  • 镜像文件和操作日志可一个存储多份,多磁盘存储

其他保障可靠性机制:

  • 快照:
  • 回收站机制
  • 安全模式

12. 如果一个 DataNode 宕机了,如何做恢复

将宕机的 DataNode 上的数据删除,重新当成新节点加入到集群即可

13. MapReduce 的执行流程

  • 预处理;CombineTextInputFormat(针对小文件多的情形)
  • 切片:切片大小为设定的切片大小上下限和Block大小的中位值,根据切片的数量启对应数量的Map数量
  • 在每个Map端调用readRecord中read()方法并发(mapper)按行读取
  • 读取内容存入OutputContainer(削峰)        #第一次IO结束
  • 环形缓冲区读取OutputContainer中的数据
  • 当环形缓冲区数据达到80%时溢写成小文件,小文件中的内容分区有序,分区内键有序,采用的排序方法为快排()    #第二次IO结束,如果有Combiner方法,会在此时执行
  • 小文件合并成大文件,归并排序,大文件分区有序,分区内键有序    #第三次IO结束
  • Reduce根据分区号读取各自对应的分区文件    #第四次IO结束
  • 读取分区文件,根据键归并排序后落盘    #第五次IO结束

14. Yarn 的 Job 提交流程

 作业提交:

        (1)client 调用 job.waitForCompletion 方法,想整个集群提交 MapReduce 作业。

        (2)client 向 ResourceManager 申请一个作业 id

        (3)ResourceManager 给 Client 返回该 job 资源的提交路径(HDFS 路径)和作业 id,每个作业都有唯一的 id

        (4)client 发送 jar 包、切片信息和配置文件到指定的资源提交路径

        (5)client 提交完资源后,向 ResourceManager 申请运行 ApplicationMaster

作业初始化:

        (6)当 ResourceManager 收到 client 的请求后,将该 job 添加到容器调度器(Resource Scheduler)中

        (7)在某一个空闲的 NodeManager 领取到该 job

        (8)该 NodeManager 创建 Container,并产生 ApplicationMaster

        (9)下载 Client 提交的资源到本地,根据分片信息生成 MapTask 和 ReduceTask

任务分配:

        (10)ApplicationMaster 向 ResourceManager 申请运行多个 MapTask 任务资源

        (11)ResourceManager 将运行 MapTask 任务分配给空闲的多个 NodeManager,NodeManager 分别领取任务并创建容器

任务运行:

        (12)ApplicationMaster 向接收到任务的 NodeManager 发送程序启动脚本,每个接收到任务的 NodeManager 启动 MapTask,MapTask 对数据进行处理,并分区排序

        (13)ApplicationMaster 等待所有 MapTask 运行完毕后,向 ResourceManager 申请容器运行 ReduceTask

        (14)程序运行完毕后,ApplicationMaster 会向 ResourceManager 申请注销自己

        (15)进度和状态更新。Yarn 中的任务将其进度和状态(包括 counter)返回给应用管理器,客户端每秒(通过 mapreduce.client.progressmonitor.pollinterval 设置)向应用管理器请求进度更新并展示给用户。可以从 Yarn WebUI 查看任务执行状态

作业完成:

        除了向应用管理器请求作业进度外,客户端每5分钟都会通过调用 waitForCompletion() 方法来检查作业是否完成。时间间隔可以通过 mapreduce.client.completion.polinterval 来设置。作业完成后,应用管理器和 container 会清理工作状态。作业的信息会被作业历史服务器存储以备之后用户核查

15. Hadoop 中数据块(Block)大小如何确定,现有一个文件大小为260M,Block大小设定为128MB,在进行 split 操作时,会生成几个 Block

        根据官网描述,Hadoop 2.7.3 版本之前,Block 默认大小为 64MB,Hadoop 2.7.3 以后,Block 默认大小为 128MB,可以通过修改hdfs-site.xml文件中的dfs.blocksize对应的值

        会产生2个 Block,因为每次切片时,都要先判断剩余部分是否大于 Block 大小的1.1倍,不大于1.1倍就划分到一个 Block

16. Block 大小设置成多少合适

  • HDFS中平均寻址时间大概为10ms;
  • 经过前任的大量测试发现,寻址时间为传输时间的1%时,为最佳状态,所以最佳传输时间:10ms/0.01=1000s=1s
  • 目前磁盘的传输速度普遍为100MB/s,最佳block大小计算:100MB/s*1s=100MB,所以我们设置block大小为128MB
  • 实际中,磁盘传输速率为200MB/s时,一般设定block大小为256MB;磁盘传输速率为400MB/s时,一般设定block大小为512MB

17. MapReduce 中有哪些关键类

GenericOptionsParser:为了 Hadoop 框架解析命令行参数的工具类

InputFormate接口可以实现的类:FileInputFormat、ComposableInputformat 等,主要用于文件为输入及切割

Mapper:将输入的 kv 对映射成中间数据 kv 对集合。Maps 将输入记录转变为中间记录

Reducer:根据 key 将中间数据集合处理合并为更小的数据结果集

Partitioner:对数据按照 key 进行分区

OutputCollecter:文件输出

Combine:本地聚合,Mapper 端的 reduce 

18. Mapper 中 setup 方法是干嘛的

setup 方法用于管理 Mapper 生命周期中的资源,加载一些初始化工作,每个 job 执行一次,setup 在完成 Mapper 构造,即将开始执行 map 动作前执行

19. Hadoop Shuffle 原理

定义:

        把 map 方法之后 reduce 方法之前这段处理过程称之为 Shuffle

具体步骤:

  • maptask 的输出数据会被写入环形缓冲区(起到削峰的作用),并记录偏移量
  • 环形缓冲区默认大小为100M,当数据达到80%即80M时,记录终止偏移量,并溢写成小文件
  • 将小文件数据进行分区,分区内进行快速排序(分区有序,分区内键有序)
  • maptask 结束后,形成的多个小文件会进行归并排序并合并成大文件(分区有序,分区内键有序)
  • 执行 reducetask 任务,去执行 maptask 的机器上拉取 属于自己分区的数据
  • reducetask 对拉取过来的数据进行归并排序(分区内键有序)

20. MapReduce 的调优

        MapReduce 优化方法主要从6个方面考虑:数据输入、Map 阶段、Reduce 阶段、IO 传输、数据倾斜和常用调优参数

数据输入:

  • 合并小文件,在执行 MapReduce 任务之前将小文件合并,大量小文件会产生大量的 map 任务,增大 map 任务装载次数,而任务的装载比较耗时,从而导致 MapReduce 运行较慢
  • 采用 CombineTextInputFormat.setMinInputSplitSize 来定义最小切片大小,解决输入端大量小文件的场景

Map 阶段:

  • 减少溢写次数,通过调整 io.sort.mb 及 sort.spill.percent 参数值,增大触发溢写的内存上限,减少溢写次数,从而减少磁盘 IO
  • 减少合并次数,通过调整 io.sort.factor 参数,增大 merge 的文件数目,减少 merge 次数,从而缩短 MapReduce 处理时间
  • 在 map 之后,不影响业务逻辑的前提下,先进行 combine 处理,减少 IO

Reduce 阶段:

  • 合理设置 map 和 reduce 数量,两个数量都不能太少或者太多,太少会导致 task 等待时间过长,延长处理时间,太多,会导致 map 和 reduce 任务之间竞争资源,造成处理超时等错误
  • 设置 map 和 reduce 共存,调整 slow start completedmaps 参数,使 map 运行到一定程度后,reduce 也开始执行,从而减少 reduce 等待时间
  • 规避使用 reduce,因为 reduce 在用于连接数据集的时候会产生大量的网络消耗
  • 合理设置 reduce 端的 buffer,可以通过设置参数来配置,使得 buffer 中的一部分数据可以直接输送到 reduce,从而减少 IO 开销。MapReduce.Reduce.input.buffer.percent 的默认值 为 0.0,当值大于 0 时,会保留在指定比例的内存读 buffer 中的数据直接拿给 reduce 使用

IO传输:

  • 采用数据压缩的方式,减少任务的 IO 时间
  • 使用 seq 二进制文件

21. Hadoop 中支持的存储格式和压缩算法

存储格式:

  • SequenceFile:以二进制键值对的形式存储数据
  • Avro:将数据定义和数据一起存储在一条消息中,其中数据定义以JSON格式存储,数据以二进制格式存储
  • RCFile:以列格式保存每个行组数据。他不是存储第一行然后是第二行,而是存储所有行上的第一列,然后是所有行上的第二列,以此类推
  • Parquet:是 Hadoop 的一种列存储格式,提供了搞笑的编码和压缩方案

压缩算法:

压缩算法压缩比压缩速度解压速度
gzip13.4%17.5 MB/s58 MB/s
bzip213.2%2.4 MB/s9.5 MB/s
lzo20.5%49.3 MB/s74.6 MB/s
snappy22.2%59.3 MB/s74.0 MB/s
  • gzip 算法

   特点:
     hadoop 内置支持,支持native库,使用方便,压缩比高
     不支持 split。
     在压缩后的文件大小与 HDFS 块大小差距不大时,可使用此算法

  应用场景:
     一天或者一个小时的日志压缩成一个 gzip 文件,运行mapreduce程序的时候通过多个gzip文件达到并发。

  • bzip2 算法

   特点:
     hadoop 内置支持,支持 split,压缩比很高,
     不支持 native 库,压缩/解压速度慢
     对于历史性很大的文件,想尽可能节省磁盘空间,还要支持split

   应用场景:
     mapreduce 的输出,压缩存档,作为冷数据使用,通常是对大文件的压缩。

  • lzo 算法

   特点:
     支持 native 库,压缩/解压速度也比较快,合理的压缩率;支持 split (需要建索引,文件修改后需要重新建索引),yum 安装 lzop 命令后,使用方便
     hadoop 内置不支持,需要手动编译安装。
     大文件的存储,作为热数据使用

   应用场景:
     一个大文件压缩后依然是两个或多个 HDFS 块的大小,还不希望作为冷数据使用

  • snappy 算法

   特点:
     高速压缩速度和合理的压缩率,支持native库
     hadoop 内置不支持,需要手动编译安装,不支持 split,没有 linux 命令可使用

   应用场景:
     mapreduce 过程中 map 的输出,reduce 或另一个 map 的输入

22. Hadoop 的资源调度器有哪些

FIFO(先入先出调度器)

Hadoop 1.x 默认调度器

只有一个队列,将一个一个 job 任务按照时间先后顺序进行服务

Capacity Scheduler(容量调度器)

hadoop 2.x 默认调度器

支持多个队列,每个队列可以配置一定量的资源,每个采用 FIFO 的方式调度

防止同一个用户的 job 任务独占队列中的资源,调度器会对同一用户提交的 job 任务所占资源进行限制

分配新的 job 任务时,首先计算每个队列中正在运行 task 个数与其队列应该分配的资源量做比值,然后选择最小的队列

其次,按照 job 任务的优先级和时间顺序,同时要考虑到用户的资源量和内存的限制,对队列中的 job 任务进行排序执行

多个队列同时按照任务队列内的先后顺序一次执行。

Fair Scheduler(公平调度器)

支持多个队列,每个队列可以配置一定资源,每个队列中的 job 任务公平共享器所在队列的所有资源

队列中的 job 任务都是按照优先级分配资源,优先级越高分配的资源越多,但是为了确保公平每个 job 任务都会分配到资源。游侠你是根据每个 job 任务的理想获取资源量减去实际获取资源量的差值决定的,差值越大优先级越高
 

以上是关于大数据—— Hadoop 常见面试题整理的主要内容,如果未能解决你的问题,请参考以下文章

大数据——Flink 常见面试题整理

大数据—— HBase 常见面试题整理

数据库常见面试题总结

java集合常见面试题进大厂必掌握---自行整理笔试题

Mybatis常见面试题汇总

关于springboot常见面试题整理笔记