介绍
零售商的商品文件已经组织好,也可以访问了。现在你能回答第一个实验中的问题:哪些商品标签出现得最频繁?几行数据可以手动统计,但不断增长的文件集合需要可重复执行的计算。
MapReduce 是组织批处理计算的一种方式。Map 将输入记录转换为键值对;Shuffle 将同一个键的值汇集起来;Reduce 将每个键的值合并为结果。对于 WordCount,键是商品标签,每次出现贡献数值 1。词频统计是用来展示数据流的小型示例,并不是完整的销售分析系统。
你将使用预置的教学工具观察这些阶段,再对相同输入运行一个真实、已预编译的 Hadoop WordCount 程序。教学工具在单个进程中打印算法阶段,并不是分布式执行轨迹。Hadoop 运行使用本地模式,便于你先关注计算,再在下一个实验中把相同算法迁移到 YARN。无需 Java 或 Python 编程。
将商品标签转换为键值对
在这一步中,你将查看输入,并追踪每次商品出现时 Map 如何处理它。
先进入本地工作目录:
cd /home/labex/project
读取六行输入:
cat /home/labex/project/data/product-words.txt
预期文本如下:
notebook pen
notebook folder
pen pen
folder notebook
notebook
folder pen
暂停一下,手动统计一种商品。notebook 出现在四行中,每行一次;pen 总共出现四次,其中第三行出现两次;folder 出现三次。程序应该产生相同总数。
键值对(key/value pair)将标签与一个值关联起来。在这个算法中,每次出现商品时,Map 都发出 (product, 1)。两次出现的 pen 会生成两个独立的键值对,并不是每行只生成一对。
提供的 wordcount-stages 可执行工具接受一个阶段名和一个本地输入文件。使用它的 map 视图:
/home/labex/project/tools/wordcount-stages map /home/labex/project/data/product-words.txt
输出开头如下:
notebook 1
pen 1
notebook 1
folder 1
每个键和值之间的间隔是一个制表符。一共有十一个键值对,每次商品出现对应一对。这个工具展示算法,不会启动 Hadoop 服务或调度任务。保存阶段输出:
/home/labex/project/tools/wordcount-stages map /home/labex/project/data/product-words.txt > /home/labex/project/output/map-pairs.txt
你改变了输入的表示形式:整行文本变成了可以按商品分组的计数贡献。
分组并归约计数贡献
在这一步中,你将追踪键值对如何经过 Shuffle 和 Reduce,并将输出与手动预测联系起来。
Map 发出独立的贡献值。要计算一种商品的总数,就必须把它的贡献值汇集在一起。Shuffle 和排序(sort)按键组织键值对,让归约任务接收到某个商品对应的值。在分布式作业中,这可能涉及任务之间的数据传输;教学工具只显示分组后的值。
查看分组视图:
/home/labex/project/tools/wordcount-stages shuffle /home/labex/project/data/product-words.txt
预期分组值如下:
folder 1,1,1
notebook 1,1,1,1
pen 1,1,1,1
键已经排序。每个逗号分隔的 1 仍代表原来的一次出现,并不是新记录。保存分组结果:
/home/labex/project/tools/wordcount-stages shuffle /home/labex/project/data/product-words.txt > /home/labex/project/output/shuffled-values.txt
Reduce(归约)合并每个键的值。这里采用整数相加。其他应用可以用不同方式合并;MapReduce 并不限于计数。
查看归约视图:
/home/labex/project/tools/wordcount-stages reduce /home/labex/project/data/product-words.txt
预期结果如下:
folder 3
notebook 4
pen 4
将这些值与第 1 步的手动计数比较。保存结果,以便接下来与真实 Hadoop 应用比较:
/home/labex/project/tools/wordcount-stages reduce /home/labex/project/data/product-words.txt > /home/labex/project/output/teaching-counts.txt
结果取决于每个键的所有出现次数,即使它们原本位于不同的行。这就是分组阶段位于映射与归约之间的原因。
运行真实的 Hadoop WordCount 程序
在这一步中,你将使用预编译的 Hadoop 示例,在本地模式执行相同的计数任务。
JAR 用来打包 Java 程序代码。Hadoop 及其示例 JAR 已经安装,你无需编译代码。hadoop jar 运行指定 JAR;wordcount 选择其中的 WordCount 示例。下面两个 -D 设置为本次调用选择本地执行框架和本地文件系统。最后两个参数是输入文件和一个新的输出目录:
hadoop jar /opt/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.5.0.jar wordcount -Dmapreduce.framework.name=local -Dfs.defaultFS=file:/// /home/labex/project/data/product-words.txt /home/labex/project/output/local-wordcount
等待提示符重新出现。Hadoop 会打印进度和诊断消息;路径、标识符和耗时会变化。这是使用本地运行器的真实 Hadoop 程序,不是 YARN 应用。本实验不启动 HDFS 或 YARN 服务,输入和输出都是本地的。
列出本地输出目录:
ls /home/labex/project/output/local-wordcount
你应该看到 _SUCCESS 标记和一个 part-... 结果文件。_SUCCESS 表示输出成功完成,结果文件则包含必须核对的数据。本地 Shell 的 part-* 模式选择结果文件。将它们合并后的内容传给 sort,让比较保持稳定:
cat /home/labex/project/output/local-wordcount/part-* | sort > /home/labex/project/output/hadoop-counts.txt
与教学工具的计数比较:
diff /home/labex/project/output/teaching-counts.txt /home/labex/project/output/hadoop-counts.txt
应该没有差异输出。你已将解释过的算法与真实程序输出联系起来。如果本次运行的输出目录已经存在,请查看已完成的文件,不要盲目删除,也不要假设重复提交会覆盖它们。
之后有一个区别很重要:HDFS 块存储字节,输入切分(input split)描述一份输入工作,任务(task)执行工作。它们彼此相关,但并非总是一一对应。结果文件是处理任务的输出,不是原始存储块的副本。
预测并测试一次输入变化
在这一步中,你将向工作副本增加一次商品出现,并测试哪个结果会改变。
保持只读的原始输入不变。使用本地 cat 和 > 写入新的可写工作副本。这里两个路径都是本地路径;你将修改输出文件:
cat /home/labex/project/data/product-words.txt > /home/labex/project/output/changed-product-words.txt
预测追加一次 notebook 后的新计数:应该只有它的总数从 4 增加到 5。printf 打印所提供的文本,\n 表示换行,>> 追加输出而不是替换现有内容:
printf 'notebook\n' >> /home/labex/project/output/changed-product-words.txt
查看修改后的输入:
cat /home/labex/project/output/changed-product-words.txt
末尾应该多出一行。只修改输入和输出路径,运行相同的 Hadoop 程序:
hadoop jar /opt/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.5.0.jar wordcount -Dmapreduce.framework.name=local -Dfs.defaultFS=file:/// /home/labex/project/output/changed-product-words.txt /home/labex/project/output/changed-wordcount
按排序顺序读取实际结果:
cat /home/labex/project/output/changed-wordcount/part-* | sort
预期结果如下:
folder 3
notebook 5
pen 4
新增的 Map 键值对属于 notebook 组,因此只有它的 Reduce 总数改变。现在你能够解释结果,而不只是识别命令是否成功。下一个实验中,算法和计数规则保持相同,由 HDFS 提供输入,YARN 管理执行资源。
总结
你将商品出现次数追踪为 Map 键值对,通过 Shuffle 对值分组,再通过 Reduce 合并。真实的 Hadoop WordCount 结果与手动计算和教学工具一致;向输入增加一次出现后,结果也按预测发生了变化。
你使用本地运行器单独学习算法。接下来将保留这一算法,学习真实 YARN 应用如何读取 HDFS 输入并生成 HDFS 结果。



