hadoop篇

Hadoop篇

hadoop 篇

问题 1 大数据如何存储?举例说明

说明 hdfs 的存储机制,不仅限于存储机制、机架感知等,这道面试题的目的不仅仅是想问你存储的机

制,而是想问你在公司是如何进行大数据存储的,这时候你就要从两方面着手回答这个问题:

1、 公司 hdfs 集群的设计方式,采用多少台机器,存储策略是什么样的

2、 存储的手段是采用的 sqoop、canel 还是 flume、logstash

问题 2 说说 mr 执行过程

1. MapTask 工作机制

整个 Map 阶段流程大体如上图所示。简单概述:input File 通过 split 被逻辑切分为多个 split 文件,通过 Record 按行读取内容给 map(用户自己实现的)进行处理,数据被 map 处理结束之后交给 OutputCollector 收集 器,对其结果 key 进行分区(默认使用 hash 分区),然后写入 buffer,每个 map task 都有一个内存缓冲区,存储着 map 的输出结果,当缓冲区快满的时候需要将缓冲区的数据以一个临时文件的方式存放到磁盘,当整个 map task 结束后再对磁盘中这个 map task 产生的所有临时文件做合并,生成最终的正式输出文件,然后等待 reduce task 来拉数据。

详细步骤:

  • 首先,读取数据组件 InputFormat(默认 TextInputFormat)会通过 getSplits 方法对输入目录中文件 进行逻辑切片规划得到 splits,有多少个 split 就对应启动多少个 MapTask。split 与 block 的对应关系默 认是一对一。

  • 将输入文件切分为 splits 之后,由 RecordReader 对象(默认 LineRecordReader)进行读取,以\n 作 为分隔符,读取一行数据,返回<key,value>。Key 表示每行首字符偏移值,value 表示这一行文本内 容。

  • 读取 split 返回<key,value>,进入用户自己继承的 Mapper 类中,执行用户重写的 map 函数。 RecordReader 读取一行这里调用一次。

  • map 逻辑完之后,将 map 的每条结果通过 context.write 进行 collect 数据收集。在 collect 中,会先对其进行分区处理,默认使用 HashPartitioner。MapReduce 提供 Partitioner 接口,它的作用就是根据 key 或 value 及 reduce 的数量来决定当前的这对输 出数据最终应该交由哪个 reduce task 处理。默认对 key hash 后再以 reduce task 数量取模。默认的取模方式只是为了平均 reduce 的处理能力,如果用户自己对 Partitioner 有需求,可以订制并设置到 job 上。

  • 接下来,会将数据写入内存,内存中这片区域叫做环形缓冲区,缓冲区的作用是批量收集 map 结果,减少磁盘 IO 的影响。我们的 key/value 对以及 Partition 的结果都会被写入缓冲区。当然写入之前,key 与 value 值都会被序列化成字节数组。 环形缓冲区其实是一个数组**,数组中存放着 key、value 的序列化数据和 key、value 的元数据信息,包 括 partition、key 的起始位置、value 的起始位置以及 value 的长度。环形结构是一个抽象概念。 缓冲区是有大小限制,默认是 100MB**。当 map task 的输出结果很多时,就可能会撑爆内存,所以需要在 一定条件下将缓冲区中的数据临时写入磁盘,然后重新利用这块缓冲区。这个从内存往磁盘写数据的过 程被称为 Spill,中文可译为溢写。这个溢写是由单独线程来完成,不影响往缓冲区写 map 结果的 线程。溢写线程启动时不应该阻止 map 的结果输出,所以整个缓冲区有个溢写的比例 spill.percent。 这个比例默认是 0.8,也就是当缓冲区的数据已经达到阈值(buffer size * spill percent = 100MB * 0.8 =* 80MB**),溢写线程启动,锁定这 80MB 的内存,执行溢写过程。Map task 的输出结果还可以往剩下的 20MB 内存中写,互不影响。

  • 当溢写线程启动后,需要对这 80MB 空间内的 key 做排序(Sort)。排序是 MapReduce 模型默认的行 为,这里的排序也是对序列化的字节做的排序。 如果 job 设置过 Combiner,那么现在就是使用 Combiner 的时候了。将有相同 key 的 key/value 对的 value 加起 来,减少溢写到磁盘的数据量。Combiner 会优化 MapReduce 的中间结果,所以它在整个模型中会多次使用。那哪些场景才能使用 Combiner 呢?从这里分析,Combiner 的输出是 Reducer 的输入,Combiner 绝不能改变最 终的计算结果。Combiner 只应该用于那种 Reduce 的输入 key/value 与输出 key/value 类型完全一致,且 不影响最终结果的场景。比如累加,最大值等。Combiner 的使用一定得慎重,如果用好,它对 job 执行效 率有帮助,反之会影响 reduce 的最终结果。

  • 每次溢写会在磁盘上生成一个临时文件(写之前判断是否有 combiner),如果 map 的输出结果真的很 大,有多次这样的溢写发生,磁盘上相应的就会有多个临时文件存在。当整个数据处理结束之后开始对磁盘中的临时文件进行 merge 合并,因为最终的文件只有一个,写入磁盘,并且为这个文件提供了一个索引 文件,以记录每个 reduce 对应数据的偏移量。 至此 map 整个阶段结束。

2.ReduceTask 工作机制

Reduce 大致分为 copy、sort、reduce 三个阶段,重点在前两个阶段。copy 阶段包含一个 eventFetcher 来获取已完成的 map 列表,由 Fetcher 线程去 copy 数据,在此过程中会启动两个 merge 线程,分别为 inMemoryMerger 和 onDiskMerger,分别将内存中的数据 merge 到磁盘和将磁盘中的 数据进行 merge。待数据 copy 完成之后,copy 阶段就完成了,开始进行 sort 阶段,sort 阶段主要是执 行 finalMerge 操作,纯粹的 sort 阶段,完成之后就是 reduce 阶段,调用用户定义的 reduce 函数进行 处理。

详细步骤:

  • Copy 阶段,简单地拉取数据。Reduce 进程启动一些数据 copy 线程(Fetcher),通过 HTTP 方式请求 maptask 获取属于自己的文件。
  • Merge 阶段。这里的 merge 如 map 端的 merge 动作,只是数组中存放的是不同 map 端 copy 来的 数值。 Copy 过来的数据会先放入内存缓冲区中,这里的缓冲区大小要比 map 端的更为灵活。merge 有三种形 式:内存到内存;内存到磁盘;磁盘到磁盘。默认情况下第一种形式不启用。当内存中的数据量到达一定 阈值,就启动内存到磁盘的 merge。与 map 端类似,这也是溢写的过程,这个过程中如果你设置有 Combiner,也是会启用的,然后在磁盘中生成了众多的溢写文件。第二种 merge 方式一直在运行,直到 没有 map 端的数据时才结束,然后启动第三种磁盘到磁盘的 merge 方式生成最终的文件。
  • 把分散的数据合并成一个大的数据后,还会再对合并后的数据排序。
  • 对排序后的键值对调用 reduce 方法,键相等的键值对调用一次 reduce 方法,每次调用会产生零个或者多个键值对, 后把这些输出的键值对写入到 HDFS 文件中。

3. Shuffle 机制

map 阶段处理的数据如何传递给 reduce 阶段,是 MapReduce 框架中 关键的一个流程,这个流程就叫 shuffle。

shuffle: 洗牌、发牌——(核心机制:数据分区,排序,规约,分组)。

shuffle 是 Mapreduce 的核心,它分布在 Mapreduce 的 map 阶段和 reduce 阶段。一般把从 Map 产生 输出开始到 Reduce 取得数据作为输入之前的过程称作 shuffle。

1).Collect 阶段:将 MapTask 的结果输出到默认大小为 100M 的环形缓冲区,保存的是 key/value, Partition 分区信息等。

2).Spill 阶段:当内存中的数据量达到一定的阀值的时候,就会将数据写入本地磁盘,在将数据写入磁盘之 前需要对数据进行一

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值