1. MapReduce的阶段分类
MapReduce 的程序在运行的过程中,一般分为两个阶段: Map 阶段和 Reduce 阶段
1.1第一阶段: Map
第一阶段,也称之为 Map 阶段。这个阶段会有若干个 MapTask 实例,完全并行运行,互不相干。每个 MapTask 会读取分析一个InputSplit (输入分片,简称分片)对应的原始数据。计算的结果数据会临时保存到所在节点的本地磁盘里。
该阶段的编程模型中会有一个 map 函数需要开发人员重写,map 函数的输入是一个 <key,value> 对,map 函数的输出也是一个<key,value> 对,key 和 value 的类型需要开发人员指定。参考下图:
1.2 第二阶段: Reduce
第二阶段,也称为 Reduce 阶段。这个阶段会有若干个 ReduceTask 实例并发运行,互不相干。但是他们的数据依赖于上一个阶段的所有MapTask 并发实例的输出。一个 ReudceTask 会从多个 MapTask 运行节点上 fetch 自己要处理的分区数据。经过处理后,输出到 HDFS上。
该阶段的编程模型中有一个 reduce 函数需要开发人员重写,reduce 函数的输入也是一个 <key,value> 对,reduce 函数的输出也是一个<key,value> 对。这里要强调的是,reduce 的输入其实就是 map 的输出,只不过 map 的输出经过 Shuffle 技术后变成了<key,List<Value>> 而已。参考下图:
注意: MapReduce 编程模型只能包含一个 map 阶段和一个 reduce 阶段,如果用户的业务逻辑非常复杂,那就只能多个 MapReduce 程序,串行运行。
2.MapReduce 编程
2.1. 第一个 MapReduce 程序
2.1.1. Hadoop Streaming
Hadoop 本身是用 Java 语言编写的,MapReduce 提供的编程接口也是 Java 的语言。不过在 Hadoop 提供的资源包中,有一个 hadoop-stream.jar
的文件,允许我们使用 Hadoop 流来处理数据。
Hadoop Streaming 是 Hadoop 附带的应用程序,可以用于执行大数据分析程序。Hadoop Streaming 可以使用 Python、Java、PHP、Scala 等语言,允许我们使用任何可执行文件或脚本来简化 MapReduce 作业。
在使用 Hadoop Streaming 的时候,我们需要使用到上方的 jar 包,同时需要指定如下参数:
参数 | 描述 |
---|---|
-file | 指定文件,可以指定 Mapper、Reducer 使用的程序源文件。 |
-mapper | 指定执行 mapper 的程序 |
-reducer | 指定执行 reducer 的程序 |
-input | 指定输入路径 |
-output | 指定输出路径 |
2.1.2. mapper
# wordcount_mapper.py
import sys
# sys.stdin: 标准输入流,逐行读取输入的内容
# 在MapReduce程序中,表示逐行读取输入文件的每一行数据
for line in sys.stdin:
# 按照空白切割单词
line = line.strip()
# 空行的处理
if line == "":
continue
word_list = line.split(" ")
# 将每一个单词配合上数字1,组成元组,写出
for word in word_list:
# 直接使用print函数,将map阶段的输出内容直接打印出来即可
print(f"%s\t%s"