基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

ApplicationMaster 申请到资源后,是如何与 NodeManager 交互来启动任务的?

知识点图片

在 Hadoop YARN 架构中,当 ApplicationMaster (AM) 向 ResourceManager (RM) 成功申请到资源(以 Container 的形式表示)后,AM 需要直接与对应的 NodeManager (NM) 进行交互来启动实际的计算任务。这个过程是绕过 RM 直接进行的(点对点通信)。

以下是 ApplicationMaster 与 NodeManager 交互并启动任务的详细流程:

1. 准备阶段:构建 ContainerLaunchContext (CLC)

AM 在联系 NM 之前,首先需要构造一个叫做 ContainerLaunchContext (容器启动上下文) 的核心对象。这个对象相当于任务的“执行蓝图”,告诉 NM 具体该如何运行这个任务。

CLC 主要包含以下关键信息:

  • Local Resources (本地资源):任务运行所需的依赖文件(如 JAR 包、配置文件、字典文件等)。AM 会指定这些文件在 HDFS 上的路径,要求 NM 下载到本地。
  • Environment Variables (环境变量):任务进程运行所需的系统环境变量(如 JAVA_HOME, CLASSPATH 等)。
  • Commands (启动命令):实际启动任务的命令行(例如 java -Xmx1g my.TaskClass 或者一段 bash 脚本)。
  • Security Tokens (安全令牌):HDFS 或其他服务的 Delegation Tokens,确保任务在 NM 上运行时有权限访问 HDFS 等组件。
  • Service Data (服务数据):特定于应用程序的数据。

2. 发起请求:AM 向 NM 发送启动指令

准备好 CLC 后,AM 会通过 RPC 协议(具体为 ContainerManagementProtocol)直接连接到分配了该 Container 的 NodeManager。

  • 调用接口:AM 调用 NM 的 startContainers() RPC 方法。
  • 身份验证:AM 在请求中必须携带 RM 之前分配的 ContainerToken。NM 会验证这个 Token,以确认 AM 确实获得了 RM 的授权来使用这些资源,防止恶意程序强占 NM 资源。

3. NM 内部处理阶段 (核心执行过程)

NodeManager 接收到 startContainers() 请求并验证通过后,会在内部经过一系列复杂的步骤来启动任务:

3.1 资源本地化 (Resource Localization)

这是 NM 最重要的一步工作。NM 的 ResourceLocalizationService 会根据 CLC 中提供的 Local Resources 列表,将 HDFS 上的 JAR 包、文件等下载到 NM 所在的物理机的本地磁盘目录中。

  • 这些资源可以被设置为 PUBLIC(所有用户可见)、PRIVATE(当前用户可见)或 APPLICATION(仅当前应用可见),NM 会根据级别进行缓存和隔离。

3.2 准备运行环境与目录

NM 会为该 Container 创建一个独立的本地工作目录,并将本地化下载的文件软链接(Symlink)到这个工作目录中。同时,NM 会将 CLC 中的环境变量写入到一个启动脚本(通常是 launch_container.sh)中。

3.3 资源隔离 (Cgroups)

如果集群配置了 LinuxContainerExecutor 并启用了 Cgroups,NM 会在操作系统层面为这个 Container 创建 Cgroups 目录,严格限制该任务能够使用的 CPU 和内存上限,防止它影响同节点上的其他任务。

3.4 启动进程

NM 将启动任务交由 ContainerExecutor 组件执行。

  • DefaultContainerExecutor:以 NodeManager 进程的操作系统用户身份启动进程(安全性较低)。
  • LinuxContainerExecutor:以提交该作业的实际用户身份(如 alicefork 出一个子进程并执行前面生成的启动脚本(安全性高,支持资源隔离)。

至此,实际的 Task 进程(例如 MapReduce 的 MapTask 或 Spark 的 Executor)就被正式拉起并运行了。

4. 运行与监控阶段:状态汇报与心跳

任务启动后,AM 和 NM 还需要保持交互以监控任务状态:

  • 状态拉取:AM 会周期性地调用 NM 的 getContainerStatuses() RPC 接口,轮询各个 Container 的运行状态(如 RUNNING, COMPLETE, FAILED 等)。
  • (补充说明:NM 也会通过心跳将 Container 的状态汇报给 RM,但 AM 主要通过直接向 NM 查询来获取实时的任务状态以便进行容错处理)

5. 结束阶段:资源清理

  • 当任务进程执行完毕(成功退出或异常崩溃)时,NM 会捕获到进程结束的信号。
  • NM 会将该 Container 的状态标记为 EXITED,清理 Cgroups 限制。
  • AM 通过轮询得知任务结束后,可以调用 stopContainers() 请求 NM 清理资源(或者 NM 在一定时间后自动清理)。
  • NM 的 DeletionService 会异步删除该 Container 的本地工作目录和私有缓存资源。
  • 最后,AM 向 RM 汇报该 Container 已使用完毕,将资源归还给集群。

总结交互时序图 (简述)

  1. AM --(构建 CLC)--> AM
  2. AM --(startContainers(ContainerToken, CLC))--> NM
  3. NM --(验证Token & 下载文件到本地)--> NM本地磁盘
  4. NM --(配置 Cgroups & 执行启动命令)--> Task OS Process
  5. AM --(getContainerStatuses())--> NM (获取任务进度)
  6. Task 结束,NM 清理本地文件。
00:00
00:00