提交并检查 YARN 批处理作业

大数据Beginner
立即练习

介绍

你已经追踪了 Map、Shuffle 和 Reduce,并核对过一次真实的本地 WordCount 运行。零售商现在希望借助环境中的资源管理服务,对 HDFS 文件应用相同的计数规则。业务问题保持不变,改变的是存储和执行安排。

YARN 为应用管理资源。它的 ResourceManager 协调资源分配,NodeManager 管理工作机器上的执行。每个提交的应用都有一个 ApplicationMaster 协调工作,并在分配的 container(容器)中运行任务;这些容器是包含进程的资源分配单位。YARN 容器不一定是 Docker 容器。

你将提交预置的 WordCount JAR,辨认它真实的 YARN 应用,检查完成状态和日志,并核对 HDFS 结果。第二次运行使用不同输出路径,让原始输入和第一次结果都保持可用。实验自行准备数据并启动服务,不需要之前实验的文件或 Java 编程技能。请使用终端完成操作。

向 YARN 提交熟悉的算法

在这一步中,你将准备 HDFS 输入,并使用已配置的 YARN 框架提交相同的 WordCount 算法。

先进入本地工作目录:

cd /home/labex/project

读取预置输入:

cat /home/labex/project/data/product-words.txt

这就是解释算法时使用的六行文本。预期总数仍然是 folder=3、notebook=4、pen=4。创建 HDFS 原始数据目录,并为结果创建独立的父目录:

hdfs dfs -mkdir -p /user/labex/yarn-batch/raw /user/labex/yarn-batch/results

上传输入:

hdfs dfs -put /home/labex/project/data/product-words.txt /user/labex/yarn-batch/raw/product-words.txt

你已知道 -put 会保留本地原件。HDFS 的 raw 目录是作业输入;results 必须位于它之外,防止把之前的输出作为新输入读取。

示例 JAR 和 wordcount 名称与本地运行相同。这次省略本地模式覆盖设置:已安装配置使用 mapreduce.framework.name=yarn,默认文件系统为 HDFS。因此下面最后两个参数都是 HDFS 路径。作业会自行创建 run-1 输出目录,该目录必须尚不存在:

hadoop jar /opt/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.5.0.jar wordcount /user/labex/yarn-batch/raw /user/labex/yarn-batch/results/run-1

等待命令返回。它会打印已提交的应用 ID,然后显示作业进度和成功完成的消息。应用和作业 ID、耗时和进度顺序会变化。无需捕捉一闪而过的 RUNNING 状态;完成后的应用仍然可以检查。

将命令与各个角色联系起来:

客户端提交应用 → ResourceManager 分配资源
ApplicationMaster 协调 MapReduce 工作 → NodeManager 运行容器
任务读取 HDFS 输入 → 任务写入 HDFS 结果

这仍是单机学习环境。虽然进程共用一台机器,YARN 的角色都是真实的。接下来,你将直接向 YARN 查询证据,确认应用成功完成。

检查已完成的应用

在这一步中,你将保留真实应用 ID,并用它查询状态和聚合日志。

YARN 接受应用时,会分配一个 Application ID(应用 ID)。它与 HDFS 路径或结果文件名不同。列出所有应用状态,包括已完成的应用:

yarn application -list -appStates ALL

这个新环境中只有一个已提交应用。它的类型应为 MAPREDUCE,状态为 FINISHED,最终状态为 SUCCEEDED。仅有 FINISHED 不能证明成功,还要查看最终状态。

保存实际应用 ID,不要从示例中复制固定值。下面的管道使用 grep -o,只打印匹配的部分。在该模式中,[0-9]* 匹配应用 ID 中的数字序列:

yarn application -list -appStates ALL | grep -o 'application_[0-9]*_[0-9]*' > /home/labex/project/output/application-id.txt

读取保存的 ID:

cat /home/labex/project/output/application-id.txt

应该看到一行以 application_ 开头的内容。其余部分由当前环境分配;不要使用其他学习者的 ID。

要把保存的值插入命令,$(cat ...) 会运行 cat,再用它的输出进行替换。双引号确保替换后的值仍是一个完整参数。查询这个实际应用:

yarn application -status "$(cat /home/labex/project/output/application-id.txt)"

找到 State、Final-State 和 Application-Type,预期分别为 FINISHED、SUCCEEDED 和 MAPREDUCE。保存报告:

yarn application -status "$(cat /home/labex/project/output/application-id.txt)" > /home/labex/project/output/application-status.txt

YARN 还会收集容器日志。logs -applicationId 命令读取所选应用的日志。将日志保存到本地,以便查看长度适中的一部分:

yarn logs -applicationId "$(cat /home/labex/project/output/application-id.txt)" > /home/labex/project/output/application.log

使用本地 tail -n 20 显示最后二十行:

tail -n 20 /home/labex/project/output/application.log

具体日志消息会变化。容器标题和任务消息将应用与 YARN 实际运行的工作联系起来。日志有助于解释行为;成功状态加上正确业务输出,比单独一行看似正常的日志更有说服力。下一个实验中,你会对失败使用相同诊断工具。

验证并重跑,保持输入不受污染

在这一步中,你将检查结果数据,将其导出,并使用第二个输出路径重新运行。

列出第一次结果目录:

hdfs dfs -ls /user/labex/yarn-batch/results/run-1

_SUCCESS 标记表示输出完成。part-* 文件保存计数。与之前一样,使用带引号的 HDFS 模式,并对记录排序以便稳定查看:

hdfs dfs -cat '/user/labex/yarn-batch/results/run-1/part-*' | sort

预期结果如下:

folder 3
notebook 4
pen 4

使用读回方法,保存排序后的本地导出文件:

hdfs dfs -cat '/user/labex/yarn-batch/results/run-1/part-*' | sort > /home/labex/project/output/run-1-counts.txt

下一次运行前,先预测相同输入再次执行是否会改变计数。应该不会。新的输出路径会保留第一次结果,并避免输出已存在的错误:

hadoop jar /opt/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.5.0.jar wordcount /user/labex/yarn-batch/raw /user/labex/yarn-batch/results/run-2

成功完成后,读取并保存第二次运行排序后的计数:

hdfs dfs -cat '/user/labex/yarn-batch/results/run-2/part-*' | sort > /home/labex/project/output/run-2-counts.txt

比较两个本地导出文件:

diff /home/labex/project/output/run-1-counts.txt /home/labex/project/output/run-2-counts.txt

应该没有差异输出。两个结果目录并列放在原始输入目录之外,因此重跑没有把先前输出加入下一次输入批次。你在不改变算法的情况下,检查了真实应用、日志、结果数据和可重复运行的行为。

总结

你将熟悉的计数算法从本地执行迁移到了 HDFS 和 YARN。你辨认了一个真实 MapReduce 应用,检查了成功完成状态和容器日志,并核对了两个输出路径中的正确结果。

算法没有改变,改变的是存储和资源管理安排。接下来,你将学习区分客户端问题与已提交应用的失败,并采取最小且合适的修复措施。