`
xujieyang4j
  • 浏览: 2456 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

YARN

    博客分类:
  • YARN
阅读更多

1. 什么是YARN

Yet Another Resource Negotiator(另一种资源协调者),是一种新的Hadoop资源管理器,它是一个通用资源管理系统,可为上层应用提供统一的资源管理和调度

2. YARN架构

  1. ResurceManager(RM):一个纯粹的调度器,专门负责集群中可用资源的分配和管理。
  2. Container :分配给具体应用的资源抽象表现形式,包括内存、cpu、disk
  3. NodeManager(NM) :负责节点本地资源的管理,包括启动应用程序的Container,监控它们的资源使用情况,并报告给RM
  4. App Master (ApplicationMaster(AM)):特定框架库的一个实例,负责有RM协商资源,并和NM协调工作来执行和监控Container以及它们的资源消耗。AM也是以一个的Container身份运行。
  5. 客户端(Client):是集群中一个能向RM提交应用的实例,并且指定了执行应用所需要的AM类型

YARN架构

MR Client和Drill Client

3. 如何编写YARN应用程序

  1. Client

    • 初始化并启动一个YarnClient
    Configuration yarnConfig = new YarnConfiguration(getConf());
    YarnClient client = YarnClient.createYarnClient();
    client.init(yarnConfig);
    client.start();
    
    • 创建一个应用程序
    YarnClientApplication app = client.createApplication();
    GetNewApplicationResponse appResponse = app.getNewApplicationResponse();
    
    • 设置应用程序提交上下文
    // 1. 设置应用程序提交上下文基本信息
    ApplicationSubmissionContext appContext = app.getApplicationSubmissionContext();
    appContext.setApplicationId(appResponse.getApplicationId());
    appContext.setApplicationName(config.getProperty("app.name"));
    appContext.setApplicationType(config.getProperty("app.type"));
    appContext.setApplicationTags(new LinkedHashSet<>(Arrays.asList(config.getProperty("app.tags").split(","))));
    // queue:默认是default
    appContext.setQueue(config.getProperty("app.queue"));
    appContext.setPriority(Priority.newInstance(Integer.parseInt(config.getProperty("app.priority"))));
    appContext.setResource(Resource.newInstance(Integer.parseInt(config.getProperty("am.memory")),
        Integer.parseInt(config.getProperty("am.vCores"))));
    
    //2. 设置am container启动上下文 
    ContainerLaunchContext amContainer = Records.newRecord(ContainerLaunchContext.class);
    
    // 3. 设置am localResources
    Map<String, LocalResource> amLocalResources = new LinkedHashMap<>();
    LocalResource drillArchive = Records.newRecord(LocalResource.class);
    drillArchive.setResource(ConverterUtils.getYarnUrlFromPath(drillArchiveFileStatus.getPath()));
    drillArchive.setSize(drillArchiveFileStatus.getLen());
    drillArchive.setTimestamp(drillArchiveFileStatus.getModificationTime());
    drillArchive.setType(LocalResourceType.ARCHIVE);
    drillArchive.setVisibility(LocalResourceVisibility.PUBLIC);
    amLocalResources.put(config.getProperty("drill.archive.name"), drillArchive);
    amContainer.setLocalResources(amLocalResources);
    
    // 4. 设置am environment
     Map<String, String> amEnvironment = new LinkedHashMap<>();
    // add Hadoop Classpath
    for (String classpath : yarnConfig.getStrings(YarnConfiguration.YARN_APPLICATION_CLASSPATH,
        YarnConfiguration.DEFAULT_YARN_APPLICATION_CLASSPATH)) {
        Apps.addToEnvironment(amEnvironment, Environment.CLASSPATH.name(),
            classpath.trim(), ApplicationConstants.CLASS_PATH_SEPARATOR);
    }
    Apps.addToEnvironment(amEnvironment, Environment.CLASSPATH.name(),
        Environment.PWD.$() + File.separator + "*", ApplicationConstants.CLASS_PATH_SEPARATOR);
    StringWriter sw = new StringWriter();
    config.store(sw, "");
    String configBase64Binary = DatatypeConverter.printBase64Binary(sw.toString().getBytes("UTF-8"));
    Apps.addToEnvironment(amEnvironment, "DRILL_ON_YARN_CONFIG", configBase64Binary,
        ApplicationConstants.CLASS_PATH_SEPARATOR);
    amContainer.setEnvironment(amEnvironment);
    
    // 5. 设置am command
    
    List<String> commands = new ArrayList<>();
    commands.add(Environment.SHELL.$$());
    commands.add(config.getProperty("drill.archive.name") + "/bin/drill-am.sh");
    commands.add("1>" + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/" + ApplicationConstants.STDOUT);
    commands.add("2>" + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/" + ApplicationConstants.STDERR);
    StringBuilder amCommand = new StringBuilder();
    for (String str : commands) {
        amCommand.append(str).append(" ");
    }
    amCommand.setLength(amCommand.length() - " ".length());
    amContainer.setCommands(Collections.singletonList(amCommand.toString()));
    
    // 6. 设置安全令牌
    if (UserGroupInformation.isSecurityEnabled()) {
        Credentials credentials = new Credentials();
        String tokenRenewer = yarnConfig.get(YarnConfiguration.RM_PRINCIPAL);
        final Token<?> tokens[] = fileSystem.addDelegationTokens(tokenRenewer, credentials);
        DataOutputBuffer dob = new DataOutputBuffer();
        credentials.writeTokenStorageToStream(dob);
        ByteBuffer fsTokens = ByteBuffer.wrap(dob.getData(), 0, dob.getLength());
        amContainer.setTokens(fsTokens);
    }
    
    appContext.setAMContainerSpec(amContainer);
    
    • 提交应用程序
    client.submitApplication(appContext);
    
  2. ApplicationMaster(AM)

    1. 初始化AMRMClientAsync
    YarnConfiguration yarnConfig = new YarnConfiguration();
    AMRMClientAsync amrmClientAsync = AMRMClientAsync.createAMRMClientAsync(5000, new AMRMCallbackHandler());
    amrmClientAsync.init(yarnConfig);
    amrmClientAsync.start();
    
    1. 初始化NMClientAsync
    YarnConfiguration yarnConfig = new YarnConfiguration();
    NMClientAsync nmClientAsync = NMClientAsync.createNMClientAsync(new NMCallbackHandler());
    nmClientAsync.init(yarnConfig);
    nmClientAsync.start();
    
    1. 注册ApplicationMaster(AM)
    String thisHostName = InetAddress.getLocalHost();
    amrmClientAsync.registerApplicationMaster(thisHostName, 0, "");
    
    1. 添加ContainerRequest
    for (NodeReport containerReport : containerReports) {
        ContainerRequest containerRequest = new ContainerRequest(capability,
            new String[] {containerReport.getNodeId().getHost()},
            null, priority, false);
        amrmClientAsync.addContainerRequest(containerRequest);
    }
    
    1. 启动容器
    private static class AMRMCallbackHandler implements AMRMClientAsync.CallbackHandler {
        @Override
        public void onContainersAllocated(List<Container> containers) {
            for (Container container : containers) {
                ContainerLaunchContext containerContext = Records.newRecord(ContainerLaunchContext.class);
    
                // setEnvironment
                Map<String, String> containerEnvironment = new LinkedHashMap<>();
                // add Hadoop Classpath
                for (String classpath : yarnConfig.getStrings(YarnConfiguration.YARN_APPLICATION_CLASSPATH,
                    YarnConfiguration.DEFAULT_YARN_APPLICATION_CLASSPATH)) {
                    Apps.addToEnvironment(containerEnvironment, Environment.CLASSPATH.name(),
                        classpath.trim(), ApplicationConstants.CLASS_PATH_SEPARATOR);
                }
                Apps.addToEnvironment(containerEnvironment, Environment.CLASSPATH.name(),
                    Environment.PWD.$() + File.separator + "*", ApplicationConstants.CLASS_PATH_SEPARATOR);
                containerContext.setEnvironment(containerEnvironment);
    
                // setContainerResource
                Map<String, LocalResource> containerResources = new LinkedHashMap<>();
                LocalResource drillArchive = Records.newRecord(LocalResource.class);
                String drillArchivePath = appConfig.getProperty("fs.upload.dir") + appConfig.getProperty(
                    "drill.archive.name");
                Path path = new Path(drillArchivePath);
                FileStatus fileStatus = FileSystem.get(yarnConfig).getFileStatus(path);
                drillArchive.setResource(ConverterUtils.getYarnUrlFromPath(fileStatus.getPath()));
                drillArchive.setSize(fileStatus.getLen());
                drillArchive.setTimestamp(fileStatus.getModificationTime());
                drillArchive.setType(LocalResourceType.ARCHIVE);
                drillArchive.setVisibility(LocalResourceVisibility.PUBLIC);
                containerResources.put(appConfig.getProperty("drill.archive.name"), drillArchive);
                containerContext.setLocalResources(containerResources);
    
                // setContainerCommand
                List<String> commands = new ArrayList<>();
                commands.add(Environment.SHELL.$$());
                commands.add(appConfig.getProperty("drill.archive.name") + "/bin/drillbit.sh run");
                commands.add("1>" + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/" + ApplicationConstants.STDOUT);
                commands.add("2>" + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/" + ApplicationConstants.STDERR);
                StringBuilder containerCommand = new StringBuilder();
                for (String str : commands) {
                    containerCommand.append(str).append(" ");
                }
                containerCommand.setLength(containerCommand.length() - " ".length());
                containerContext.setCommands(Collections.singletonList(containerCommand.toString()));
    
                nmClientAsync.startContainerAsync(container, containerContext);
            }
    
        }
    }
    
    1. unregisterApplicationMaster(AM)
    amrmClientAsync.unregisterApplicationMaster(appStatus, appMessage, null);
    

客户端发给ResourceManager的资源请求示例

ApplicationMaster和NodeManager的交互

5. 为什么会有YARN

  1. 可扩展性:实践证明在MRv1中要将JobTracker扩展至4000个节点规模是极度困难,因为JobTarcker承担太多的职责,包括资源的调度,任务的跟踪和监控,当节点规模越来越大时,JobTracker编程越来越不堪重负。而在YARN中,JobTarcker被拆分为了RM和AM,职责更清晰,每个组件承担的职责变少,更加的轻量级。
  2. 对编程模型多样性的支持:由于MRv1中JobTarcker和TaskTarckerde的设计和MR框架耦合验证,导致MRv1仅仅支持mapreduce计算框架,对并行计算、流式计算、内存计算不支持。而在YARN中具体的框架由AM负责,是应用程序自己控制,YARN提供了统一的资源调度。
  3. 框架升级更容易:在MRv1中若要对MR框架升级,则需要重启整个Hadoop集群,风险很大。而在YARN中,具体的框架由AM负责,是应用程序自己控制,所以只需升级用户程序库即可。
  4. 集群资源利用率:MRv1引入了“slot”概念表示各个节点上的计算资源,将各个节点上的资源(CPU、内存和磁盘等)等量切分成若干份,每一份用一个slot表示,同时规定一个task可根据实际需要占用多个slot,slot又被分为Mapslot和Reduceslot两种,但不允许共享。对于一个作业,刚开始运行时,Map slot资源紧缺而Reduce slot空闲,当Map Task全部运行完成后,Reduce slot紧缺而Map slot空闲,很明显,降低了资源的利用率。而在YARN中,资源以Container形式表现,包含了内存、cpu等,相比MRv1,资源抽象粒度更细,其次,通过RM的Scheduler(FIFO、Capacity、Fair),保障资源的弹性。

6. 参考资料

  1. 《HadoopYARN权限指南》
  2. 《Hadoop技术内幕 深入解析YARN架构设计与实现原理》
分享到:
评论

相关推荐

    Yarn获取Application列表编码

    Yarn 获取 Application 列表编码 Yarn 是一个资源管理和调度框架,负责管理 Hadoop 集群中的资源和应用程序。获取 Application 列表编码是 Yarn 中的一种常见操作,本文将对其进行详细的分析和介绍。 Yarn 获取 ...

    yarn-1.22.4.msi和yarn-1.22.5.msi

    Yarn是JavaScript社区广泛使用的包管理工具,它旨在提高npm(Node.js的包管理器)的性能、可预测性和安全性。这两个文件,"yarn-1.22.4.msi" 和 "yarn-1.22.5.msi",是Yarn的特定版本安装程序,适用于Windows操作...

    yarn 1.6 WIN安装文件

    **Yarn 1.6 在Windows上的安装指南** Yarn是一款高效的依赖管理工具,它为JavaScript项目提供了可靠的、可重复的以及快速的包管理解决方案。本指南将详细介绍如何在Windows操作系统上安装Yarn 1.6版本。 1. **了解...

    Hadoop的yarn详解

    Hadoop的YARN架构是Hadoop版本2.x引入的一个重要组件,它负责处理资源管理和作业调度,而核心的计算任务处理则交给了MapReduce、Tez、Spark等计算框架。YARN的出现是为了解决Hadoop早期版本中的可扩展性问题,它通过...

    Yarn编程ApplicationList

    在分布式计算领域,Apache Hadoop YARN(Yet Another Resource Negotiator)是核心组件之一,它作为资源管理系统,负责调度和管理Hadoop集群上的应用程序。在这个主题中,我们将深入探讨"Yarn编程ApplicationList",...

    yarn 前端打包工具指定配置文件

    在前端开发领域,`Yarn` 是一个非常流行的依赖管理工具,它被广泛用于替代 `npm` 进行包的安装和管理。`Yarn` 提供了更快的速度、更可靠的重复性和更好的安全性。在某些情况下,我们可能需要对前端项目进行特定的...

    yarn-1.19.2.msi

    Yarn 对你的代码来说是一个包管理器, 你可以通过它使用全世界开发者的代码,或者分享自己的代码。 Yarn 做这些快捷、安全、可靠,所以你不用担心什么。 通过Yarn你可以使用其他开发者针对不同问题的解决方案,使...

    yarn-1.22.0.msi

    此外,Yarn提供了`yarn upgrade`、`yarn remove`、`yarn info`等命令,用于升级依赖、移除依赖和查看依赖信息。还有`yarn install --offline`命令,可以在没有网络的情况下利用本地缓存安装依赖。 总之,Yarn作为一...

    hadoop-yarn-api-2.5.1-API文档-中文版.zip

    赠送jar包:hadoop-yarn-api-2.5.1.jar; 赠送原API文档:hadoop-yarn-api-2.5.1-javadoc.jar; 赠送源代码:hadoop-yarn-api-2.5.1-sources.jar; 赠送Maven依赖信息文件:hadoop-yarn-api-2.5.1.pom; 包含翻译后...

    yarn-1.22.0.zip

    **Yarn 1.22.0:高效且可靠的JavaScript包管理器** Yarn是Facebook在2016年推出的JavaScript包管理工具,它旨在解决npm(Node.js的默认包管理器)在处理依赖关系时的一些痛点,如不一致的安装结果、缓慢的安装速度...

    hadoop-yarn-client-2.6.5-API文档-中文版.zip

    赠送jar包:hadoop-yarn-client-2.6.5.jar; 赠送原API文档:hadoop-yarn-client-2.6.5-javadoc.jar; 赠送源代码:hadoop-yarn-client-2.6.5-sources.jar; 赠送Maven依赖信息文件:hadoop-yarn-client-2.6.5.pom;...

    yarn1.22.4与1.22.5最新安装包windows

    Yarn是Facebook开发的一款流行的JavaScript包管理工具,它在npm(Node Package Manager)的基础上提供了更快、更可靠和更安全的包管理和依赖关系解决方式。在本文中,我们将深入探讨Yarn 1.22.4和1.22.5这两个版本在...

    最新yarn-1.22.5的windows的msi安装版本

    **Yarn 1.22.5 Windows MSI 安装详解** Yarn 是一个现代的、高性能的包管理器,它被广泛应用于JavaScript开发中,用于管理和安装项目依赖。相较于npm,Yarn 提供了更稳定的环境、更快的安装速度以及更好的并行处理...

    Spark实验:On Yarn模式安装部署(带答案)1

    Spark on Yarn是一种将Spark应用程序部署在Hadoop YARN资源管理器上的方法,它允许Spark充分利用YARN的资源管理和调度功能。在这个实验中,我们将详细探讨如何在Yarn模式下安装和部署Spark集群。 首先,我们需要...

    yarn.tar.gz

    【标题】"yarn.tar.gz" 是一个归档文件,它使用了gzip压缩算法来减小文件大小。在IT行业中,这种格式常用于分发软件、源代码或数据集,以便于下载和存储。"tar"是Linux和Unix系统中的一个工具,用于将多个文件和目录...

    yarn-v1.22.5.tar.gz

    Yarn 的使用方法基本与 npm 类似,比如 `yarn init` 创建新项目,`yarn add` 添加依赖,`yarn remove` 移除依赖,`yarn upgrade` 升级依赖,`yarn install` 安装项目依赖等。然而,由于 Yarn 的特性,这些操作的执行...

    yarn-v1.19.1.tar.gz

    Yarn是JavaScript的世界中一个流行的包管理工具,它在2016年由Facebook推出,旨在解决npm(Node Package Manager)的一些性能和可预测性问题。`yarn-v1.19.1.tar.gz`是一个包含Yarn源码的压缩包,版本号为1.19.1。这...

    hadoop-yarn-client-2.7.3-API文档-中英对照版.zip

    赠送jar包:hadoop-yarn-client-2.7.3.jar; 赠送原API文档:hadoop-yarn-client-2.7.3-javadoc.jar; 赠送源代码:hadoop-yarn-client-2.7.3-sources.jar; 赠送Maven依赖信息文件:hadoop-yarn-client-2.7.3.pom;...

    node12.2_yarn1.22.5安装包

    在Windows环境下进行前端开发,Node.js和Yarn是两个至关重要的工具。`node12.2_yarn1.22.5安装包`是专为Windows开发者设计的,包含了Node.js v12.22.1和Yarn v1.22.5的安装文件,确保了开发环境的一键式搭建。 **...

    hadoop 2.9.0 yarn-default.xml 属性集

    在YARN中,yarn-site.xml文件是用于配置YARN服务的属性集,其中包含了YARN运行所依赖的各种参数及其默认值和作用描述。 以下是一些yarn-site.xml中定义的关键属性及其解释: 1. yarn.resourcemanager.hostname:此...

Global site tag (gtag.js) - Google Analytics