文章目录
推荐阅读:Hadoop 2.x
3.1 Hadoop 常用端口号
- dfs.namenode.http-address : 50070
- SecondaryNameNode : 50090
- dfs.datanode.address : 50010
- fs.defaultFS : 8020或9000
- yarn.resourcemanager.webapp.address : 8088
- 历史服务器 web 访问端口 : 19888
3.2 配置文件以及简单的 Hadoop 集群搭建
(1) 配置文件:
- hadoop-env.sh
- core-site.xml
- mapred-site.xml
- hdfs-site.xml
(2) 简单的集群搭建过程
- 配置 SSH 免密登录
- 解压 Hadoop 压缩包
- 配置 Hadoop 核心文件 hadoop-env.sh,core-site.xml,mapred-site.xml,hdfs-site.xml
- 配置 Hadoop 环境变量
- 格式化 NameNode
3.3 HDFS 读流程
3.4 HDFS 写流程
3.5 MapReduce 过程发生了多少次排序?
总共可能发生 4次排序 过程:
(1)Map 阶段:
- 环形缓冲区内,对输出的key进行按照字典进行快速排序。
- 对溢写文件进行分区归并排序,例如把相同的字段存放到一个分区(在reduce阶段,可能来自多个map进行排序)
(2)Reduce 阶段:
- 按指定分区读取到 reduce 缓存中:进行归并排序,再次进行分区,因为key可能来自不同的map,要把相同的key再次存储到相同的分区中
- Reduce Task 前分组排序:自定义
3.6 MapReduce 的工作原理
推荐阅读:
https://www.cnblogs.com/npumenglei/p/3631244.html
https://juejin.cn/post/6844903607498702856
3.6.1 工作流程图
3.6.2 举例详解
创建两个文本文件作为输入:
File 1 内容:
My name is Tony
My company is pivotal
File 2 内容:
My name is Lisa
My company is EMC
(1)Map
输入的两个文件默认情况就是两个 split ,这两个 split 默认会分给两个 Mapper 处理。然后 MR 会把文件内容进行 Map,主键 Key 是单词,值 Value 是1 。
那么两个 Mapper 的输出就是:
split 0 内容:
My 1
name 1
is 1
Tony 1
My 1
company 1
is 1
Pivotal 1
split 1 内容:
My 1
name 1
is 1
Lisa 1
My 1
company 1
is 1
EMC 1
(2)Partition
MR 每次读取 split 的数据(一行一行地读取)放到环形缓冲区中,然后进行分区,当缓冲区满了之后,会首先对缓冲区进行排序,然后溢写磁盘。
由于会有多个 Reducer,所以要对数据进行分区,每个 Reducer 只需要处理对应的 Partition就可以了。
主要的分区方法是按照 key 的不同,把数据分开。但要注意保证 key 的唯一性,因为 Reduce 阶段是在不同的 Reducer 节点上做的,假如同一个 key 存在于两个 Reducer 节点上,结果就会出问题。所以很常见的 Partition 方法就是哈希。
分区后,两个 split 文件如下:
split 0 内容:
Partition 1:
company 1
is 1
is 1
Partition 2:
My 1
My 1
name 1
Pivotal 1
Tony 1
split 1 内容:
Partition 1:
company 1
is 1
is 1
EMC 1
Partition 2:
My 1
My 1
name 1
Lisa 1
其中 Partition 1 将来是准备给 Reducer 1 处理的, Partition 2 是给 Reducer 2 的
这里我们可以看到, Partition 只是把所有的条目按照 Key 分了一下区, 没有其他任何处理, 每个区里面的 Key 都不会出现在另外一个区里面。
(3)Sort
当缓冲区满了之后,需要溢写磁盘。在溢写之前,对缓冲区中各个分区内的数据进行排序, 这里可以看到, 每个 partition 里面的条目都按照Key的顺序做了排序。
排序方式是,先按照分区编号 partition 进行排序,然后按照 key 进行排序。这样,经过排序后,数据以分区为单位聚集在一起,且同一分区内所有数据按照 key 有序。
split 0 内容:
Partition 1:
company 1
is 1
is 1
Partition 2:
My 1
My 1
name 1
Pivotal 1
Tony 1
split 1 内容:
Partition 1:
company 1
EMC 1
is 1
is 1
Partition 2:
Lisa 1
My 1
My 1
name 1
(4)Combine
这一步是可选流程。可以理解为一个 mini Reduce 过程,它发生在前面Map的输出结果之后, 目的就是在结果送到Reducer之前先对其进行一次计算, 以减少文件的大小, 方便后面的传输。 但这步也不是必须的。
split 0 内容:
Partition 1:
company 1
is 2
Partition 2:
My 2
name 1
Pivotal 1
Tony 1
split 1 内容:
Partition 1:
company 1
EMC 1
is 2
Partition 2:
Lisa 1
My 2
name 1
我们可以看到, 针对前面的输出结果, 我们已经局部地统计了is 和 My的出现频率, 减少了输出文件的大小。
(5)Merge
本例中的每个 split 文件仅有1个 partition 1 和 partition 2 ,但实际中,每个 split 文件的同一个 partition 有可能会生成多个 partition 文件(因为缓冲区满了之后会溢写到磁盘)。
因此磁盘中会生成很多个溢写小文件,这些小文件内部是有序的,但小文件和小文件之间是无序的,所以需要一次归并排序形成一个全盘有序的文件。
(6)Copy
接下来就要把 Map 阶段的输出结果给 Reducer了,这个阶段被称为 Copy。实现的时候,是通过 http 的方式,由 Reducer 节点向各个 Mapper 节点下载属于自己分区的数据。
那么根据前面的 Partition,下载完的结果如下:
Reducer 节点 1 共包含两个文件:
Partition 1:
company 1
is 2
Partition 1:
company 1
EMC 1
is 2
Reducer 节点 2 也是两个文件:
Partition 2:
My 2
name 1
Pivotal 1
Tony 1
Partition 2:
Lisa 1
My 2
name 1
这里可以看到, 通过 Copy , 相同 Partition 的数据落到了同一个 Reducer 节点上。
(7)Merge
如上一步所示, 此时 Reducer 得到的文件是从不同 Mapper 那里下载到的, 需要对他们进行合并为一个文件, 所以下面这一步就是 Merge , 结果如下:
Reducer 节点1的内容:
company 1
company 1
EMC 1
is 2
is 2
Reducer 节点2的内容:
Lisa 1
My 2
My 2
name 1
name 1
Pivotal 1
Tony 1
(8)Reduce
这一步就是根据每个文件中的内容最后做一次统计, 结果如下:
Reducer 节点1的内容:
company 2
EMC 1
is 4
Reducer 节点2的内容:
Lisa 1
My 4
name 2
Pivotal 1
Tony 1
至此大功告成! 我们成功统计出两个文件里面每个单词的数目, 同时把它们存入到两个输出文件中, 这两个输出文件也就是传说中的 part-r-00000 和 part-r-00001。
3.7 Shuffle 机制
数据从 map 输出到 reducer 输入的过程称为 shuffle。
Shuffle的流程就是:分区 -> 排序 -> 溢写
3.8 Map Join
数据倾斜就是数据的 key 的分化严重不均,造成一部分数据很多,一部分数据很少的局面。如下图所示,数据经过map之后,由于不同 key 的数据量分布不均,某些 partition 中的数据特别多,从而造成处理该 partition 的 reducer 任务量特别大。
Map Join :
- 适用于一张表大,一张表小的场景
- 在 Map 端缓存多张表,提前处理业务逻辑,这样增加 Map 端业务,减少 Reduce 端数据的压力,尽可能的减少数据倾斜
tips:Map join 是 MR 的一种很好的优化手段,大家在复习 Hadoop 优化的时候可以将 Hive 优化联系起来,因为我们数仓中使用的依旧是 MR 引擎(其他提示:ORC)
3.9 压缩
在写磁盘的时候采用压缩的方式将 map 的输出结果进行压缩是一个减少网络开销很有效的方法。
tips:如果面试过程问到,我们一般回答压缩方式为 Snappy,特点是速度快,缺点是无法切分。