YARN 的任务提交流程是怎样的?思维导图 代码示例(java 架构)

YARN的任务提交流程是一个复杂但有序的过程,它涉及到多个组件之间的交互。以下是详细的任务提交流程描述、思维导图结构化描述以及Java代码示例,帮助你理解如何在YARN中提交任务。

YARN 任务提交流程

  1. 客户端提交应用程序

    • 客户端通过YARN的API向ResourceManager提交一个新应用程序。
    • 提交时需要提供ApplicationMaster的启动信息(如JAR包路径、主类名等)以及其他配置参数。
  2. ResourceManager分配资源

    • ResourceManager接收到应用程序提交请求后,为该应用程序分配一个唯一的Application ID,并预留一部分资源用于启动ApplicationMaster。
  3. NodeManager启动ApplicationMaster

    • ResourceManager通知某个NodeManager使用预留的资源启动ApplicationMaster容器。
    • NodeManager根据提供的启动上下文(Container Launch Context),下载必要的文件和依赖项,并启动ApplicationMaster进程。
  4. ApplicationMaster注册到ResourceManager

    • ApplicationMaster启动后,会向ResourceManager注册自己,并报告其状态。
    • ResourceManager将ApplicationMaster的信息记录下来,以便后续通信。
  5. ApplicationMaster申请资源

    • ApplicationMaster根据应用程序的需求,通过与ResourceManager的RPC接口,请求更多资源来运行任务(例如Map或Reduce任务)。
    • ResourceManager按照调度策略分配资源给ApplicationMaster。
  6. NodeManager启动任务容器

    • 当ResourceManager批准了资源请求后,它会告知相应的NodeManager启动新的任务容器。
    • NodeManager负责创建并管理这些容器,同时将任务启动命令发送给容器执行。
  7. 任务执行与监控

    • 在容器中运行的任务开始处理数据,并将进度更新和状态信息反馈给ApplicationMaster。
    • ApplicationMaster持续监控所有任务的状态,必要时进行故障恢复或其他操作。
  8. 完成与清理

    • 应用程序完成后,ApplicationMaster会通知ResourceManager释放所有资源,并结束自身。
    • ResourceManager从系统中移除应用程序的相关记录,NodeManager则负责清理已终止的任务容器。

思维导图结构化描述

YARN任务提交流程
├── 客户端提交应用程序
│   ├── 提供AM启动信息
│   └── 提供其他配置参数
├── ResourceManager分配资源
│   ├── 分配唯一Application ID
│   └── 预留资源启动AM
├── NodeManager启动ApplicationMaster
│   ├── 下载必要文件和依赖项
│   └── 启动AM进程
├── ApplicationMaster注册到ResourceManager
│   └── 报告状态
├── ApplicationMaster申请资源
│   ├── 请求更多资源
│   └── 按照调度策略分配资源
├── NodeManager启动任务容器
│   ├── 创建并管理容器
│   └── 发送任务启动命令
├── 任务执行与监控
│   ├── 处理数据
│   └── 更新进度和状态
└── 完成与清理
    ├── 释放资源
    ├── 结束AM
    └── 清理任务容器

伪代码示例 (Java架构)

// 示例:提交应用程序到YARN集群
public class YarnAppSubmitter {

    public static void main(String[] args) throws Exception {
        // 初始化配置和YARN客户端
        Configuration conf = new Configuration();
        YarnClient yarnClient = YarnClient.createYarnClient();
        yarnClient.init(conf);
        yarnClient.start();

        // 获取新的应用程序ID
        GetNewApplicationRequest request = Records.newRecord(GetNewApplicationRequest.class);
        GetNewApplicationResponse response = yarnClient.getNewApplication(request);

        // 创建应用程序提交上下文
        ApplicationSubmissionContext appContext = createApplicationSubmissionContext(yarnClient, response);

        // 提交应用程序
        yarnClient.submitApplication(appContext);

        // 关闭YarnClient
        yarnClient.stop();
    }

    private static ApplicationSubmissionContext createApplicationSubmissionContext(YarnClient yarnClient, GetNewApplicationResponse response) throws YarnException, IOException {
        ApplicationSubmissionContext context = Records.newRecord(ApplicationSubmissionContext.class);
        context.setApplicationId(response.getApplicationId());
        context.setQueue("default"); // 设置队列名称
        context.setApplicationName("MyYarnApp");

        // 设置ApplicationMaster容器启动上下文
        ContainerLaunchContext amContainer = createContainerLaunchContext();
        context.setAMContainerSpec(amContainer);

        // 设置资源需求
        Resource resource = Records.newRecord(Resource.class);
        resource.setMemory(1024); // 1GB内存
        resource.setVirtualCores(1); // 1个虚拟CPU核心
        context.setResource(resource);

        return context;
    }

    private static ContainerLaunchContext createContainerLaunchContext() throws IOException {
        ContainerLaunchContext amContainer = Records.newRecord(ContainerLaunchContext.class);

        // 添加环境变量
        Map<String, String> env = new HashMap<>();
        env.put("CLASSPATH", "${CLASSPATH}:/path/to/classes");
        amContainer.setEnvironment(env);

        // 添加本地资源(如jar包)
        Map<String, LocalResource> localResources = new HashMap<>();
        Path amJarPath = new Path("/path/to/am.jar");
        LocalResource resource = Records.newRecord(LocalResource.class);
        resource.setType(LocalResourceType.FILE);
        resource.setVisibility(LocalResourceVisibility.APPLICATION);
        resource.setResource(ConverterUtils.getYarnUrlFromPath(amJarPath));
        resource.setSize(-1);
        resource.setTimestamp(-1);
        localResources.put("am.jar", resource);
        amContainer.setLocalResources(localResources);

        // 设置命令行参数
        List<String> commands = new ArrayList<>();
        commands.add("$JAVA_HOME/bin/java");
        commands.add("-Xmx1024M");
        commands.add("com.example.MyApplicationMaster");
        commands.add("1>");
        commands.add(ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/stdout");
        commands.add("2>");
        commands.add(ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/stderr");
        amContainer.setCommands(commands);

        return amContainer;
    }
}

这段代码展示了如何使用YARN Java API来提交一个简单的应用程序。YarnAppSubmitter类负责初始化YARN客户端,获取一个新的应用程序ID,创建应用程序提交上下文,并最终提交应用程序。此外,还展示了如何设置ApplicationMaster的容器启动上下文,包括指定环境变量、本地资源(例如JAR文件)和命令行参数。

通过上述内容,你应该能够更好地理解YARN的任务提交流程及其背后的机制,并且知道如何编写Java代码来实现这一过程。这不仅有助于开发基于YARN的应用程序,还能帮助你更有效地管理和优化Hadoop集群中的资源利用。

你可能感兴趣的:(java,架构,开发语言)