前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >YARN的机架感知功能

YARN的机架感知功能

原创
作者头像
醉独醒
修改于 2022-06-06 02:11:09
修改于 2022-06-06 02:11:09
1.2K0
举报
文章被收录于专栏:大数据-yarn大数据-yarn

最近几天做Hadoop机架感知功能时,在网上可以找到很多关于HDFS机架感知的资料,但是对于YARN机架感知的介绍却很少。这篇文章最主要就是说明机架感知功能对于YARN来说起到的作用,若有理解的偏差请指正。谢谢。

*注:代码基于3.1.1*

1 前言

1.1 Hadoop机架感知功能对于HDFS

HDFS的默认副本数是3个,在未启用Hadoop机架感知功能时,数据的备份是随机的,有可能同一个DataNode节点有多个副本,也有可能所有的3个副本都在同一个机架,这样如果一个节点宕机或整个机架出现问题,数据就会丢失。

在开启Hadoop机架感知功能后,本地会存储一份, 同机架的某个节点存储一份,不同机架的某个节点存储一份。这样保证了如果本地数据损坏,首先会在同机架的节点上获取数据;如果整个机架出现问题,也可以保证从其他机架上获取数据。

Hadoop的机架感知功能使得HDFS在读取数据时降低了整体的带宽消耗和读取延时,也保证了数据不会轻易丢失。

1.2 Hadoop机架感知功能对于YARN

Hadoop机架感知功能对于YARN最直观的表现,可以通过ResourceManager的管理界面(ResourceManagerIP:8088/cluster/nodes)查看各个NodeManager所属机架,未启用Hadoop机架感知功能时,默认的机架就为/default-rack。这个可以结合NodeManager的健康检查功能,很快的定位出现问题节点所在的物理位置。

并且Hadoop机架感知还会影响YARN中Container启动时所在节点。Container首先会选择数据所在节点启动,如果该节点资源不足,则会在与该节点同机架的节点启动。如果该机架的节点资源都不足,则在其他节点启动。

2 启用Hadoop机架感知功能

2.1 相关配置

配置项

默认值

配置说明

net.topology.node.switch.mapping.impl

org.apache.hadoop.net.ScriptBasedMapping

DNSToSwitchMapping的实现类。当配置为"org.apache.hadoop.net.ScriptBasedMapping"时,它调用“net.topology.script.file.name”中指定的脚本来解析节点所属机架。如果“net.topology.script.file.name”的值为空,所有节点的机架信息都为"/default-rack"

net.topology.script.file.name

解析机架拓扑关系的脚本名。例如:如果192.168.0.1所属机架为/rack1,则将“192.168.0.1”作为参数传入脚本,则会返回/rack1为输出。

2.2 功能的启用

"net.topology.node.switch.mapping.impl"配置项是拓扑解析的实现类,用户可以自己编写Java程序来解析机架信息。我们这里使用它的默认值“org.apache.hadoop.net.ScriptBasedMapping”来实现Hadoop的机架感知功能。

2.2.1 脚本的编写

一个脚本的实例如下所示,里面包含了每个IP所对应的rack信息,可以将这个脚本放在/home目录下,脚本名字为 topology-rack.sh。

代码语言:shell
AI代码解释
复制
#!/usr/bin/python

#-\*-coding:utf-8 -\*-

import sys

rack = {

"192.168.0.1":"/room1-rack1",

"192.168.0.2":"/room1-rack1",

"192.168.0.3":"/room1-rack2",

"192.168.0.4":"/room1-rack2",

"192.168.0.5":"/room2-rack1",

"192.168.0.6":"/room2-rack1",

"192.168.0.7":"/room2-rack2"

}



if \_\_name\_\_=="\_\_main\_\_":

  print "/"+rack.get(sys.argv[1],"/default-rack")

将配置项“net.topology.script.file.name”配置如下:

代码语言:txt
AI代码解释
复制
  <property>

        <name>net.topology.script.file.name</name>

        <value>/home/topology-rack.sh</value>

  </property>

重启HDFS和YARN之后,就可以开启Hadoop机架感知功能。

**注:如果DataNode或NodeManager扩容,要及时修改脚本文件当中的拓扑关系,否则会默认扩容节点为/default-rack机架**

3 YARN机架感知的源码分析

3.1 初始化过程

YARN中,主要在RackResolver类中处理机架信息。下面介绍该类的主要功能。

首先看其的初始化方法,RackResolver.init()

  • 获取net.topology.node.switch.mapping.impl配置,初始化机架感知处理类。
代码语言:java
AI代码解释
复制
  public synchronized static void init(Configuration conf) {

    ....

    Class<? extends DNSToSwitchMapping> dnsToSwitchMappingClass =

        conf.getClass(

        CommonConfigurationKeysPublic.NET\_TOPOLOGY\_NODE\_SWITCH\_MAPPING\_IMPL\_KEY,

        ScriptBasedMapping.class,

        DNSToSwitchMapping.class);

    try {

      DNSToSwitchMapping newInstance = ReflectionUtils.newInstance(

          dnsToSwitchMappingClass, conf);



      dnsToSwitchMapping =

          ((newInstance instanceof CachedDNSToSwitchMapping) ? newInstance

              : new CachedDNSToSwitchMapping(newInstance));

    } catch (Exception e) {

      throw new RuntimeException(e);

    }

  }

初始化机架感知处理类时,会通过ScriptBasedMapping的构造函数,初始化一些参数:

  1. 初始化解析脚本的存放路径;
  2. 初始化脚本入参最大个数。
代码语言:java
AI代码解释
复制
    public void setConf (Configuration conf) {

      super.setConf(conf);

      if (conf != null) {

        scriptName = conf.get(SCRIPT\_FILENAME\_KEY);

        maxArgs = conf.getInt(SCRIPT\_ARG\_COUNT\_KEY, DEFAULT\_ARG\_COUNT);

      } else {

        scriptName = null;

        maxArgs = 0;

      }

    }

3.2 获取主机与机架的相应关系

3.2.1 建立主机名与机架的对应关系

YARN会通过RackResolver.coreResolve()方法来获取主机名和机架信息的对应关系,具体如下:

  1. 通过dnsToSwitchMapping.resolve(tmpList)获取主机与机架的信息,其具体解析过程3.2.2介绍;
  2. 默认机架信息为DEFAULT\_RACK,如果主机解析机架信息时为空,则其机架信息为默认值;
  3. 创建并返回一个主机名与机架信息对应的Node
代码语言:java
AI代码解释
复制
  private static Node coreResolve(String hostName) {

    List <String> tmpList = Collections.singletonList(hostName);

    List <String> rNameList = dnsToSwitchMapping.resolve(tmpList);

    String rName = NetworkTopology.DEFAULT\_RACK;

    if (rNameList == null || rNameList.get(0) == null) {

      LOG.debug("Could not resolve {}. Falling back to {}", hostName,

            NetworkTopology.DEFAULT\_RACK);

    } else {

      rName = rNameList.get(0);

      LOG.debug("Resolved {} to {}", hostName, rName);

    }

    return new NodeBase(hostName, rName);

  }

3.2.2 从缓存中获取主机名对应机架信息

接下来对3.2.1中所提到的dnsToSwitchMapping.resolv(List<String> names)进行说明。dnsToSwitchMappingCachedDNSToSwitchMapping的一个实例,会调用CachedDNSToSwitchMapping.resolve()方法,其说明如下:

  1. 将主机名转换为主机IP;
  2. 通过getUncachedHosts(names)获取没存放在缓存中的主机IP;
  3. 调用rawMapping.resolve(uncachedHosts)来解析未在缓存中主机的机架信息,具体解析过程3.2.3中介绍;
  4. uncachedHostsresolvedHosts信息对应的存放到缓存中;
  5. 再从缓存中读取主机IP对应的机架信息,并返回。

***注:由第2条可知,在NodeManager扩容时,将其信息更新到脚本就可以。但是如果修改一个已存在的NodeManager的机架信息,需要重启YARN服务生效(更新缓存)。***

代码语言:java
AI代码解释
复制
  public List<String> resolve(List<String> names) {

    names = NetUtils.normalizeHostNames(names);

    ...

    List<String> uncachedHosts = getUncachedHosts(names);



    // Resolve the uncached hosts

    List<String> resolvedHosts = rawMapping.resolve(uncachedHosts);

    //cache them

    cacheResolvedHosts(uncachedHosts, resolvedHosts);

    //now look up the entire list in the cache

    return getCachedHosts(names);

  }

3.2.3 从脚本中解析主机对应的机架信息

rawMapping.resolve(uncachedHosts)中,实际调用的是ScriptBasedMapping#RawScriptBasedMapping.resolve()方法,其说明如下:

  1. 判断脚本信息是否为空(详见3.1);
  2. 通过脚本获取主机IP对应的机架信息(runResolveCommand()方法就是判断下传参是否符合要求,并且执行脚本,并将脚本执行结果返回),经过处理后返回。
代码语言:java
AI代码解释
复制
public List<String> resolve(List<String> names) {

      List<String> m = new ArrayList<String>(names.size());

      if (scriptName == null) {

      for (String name : names) {

        m.add(NetworkTopology.DEFAULT\_RACK);

      }

        return m;

      }

      ...

      String output = runResolveCommand(names, scriptName);

      if (output != null) {

        StringTokenizer allSwitchInfo = new StringTokenizer(output);

        while (allSwitchInfo.hasMoreTokens()) {

          String switchInfo = allSwitchInfo.nextToken();

          m.add(switchInfo);

        }

      ...

      return m;

    }

3.3 主机与机架信息的调用

ResourceTrackerService.resolve()AMRMClientImpl.resolveRacks()RMContainerAllocator.assignMapsWithLocality()TaskAttemptImpl的构造函数和TaskAttemptImpl.computeRackAndLocality()中都调用了RackResolver.resolve()方法来获取主机与机架的信息。

  1. ResourceTrackerService中,用其信息用在NodeManagerResourceManager注册的过程中;
  2. AMRMClientImpl中,其信息用在添加containerRequest当中;
  3. RMContainerAllocatorTaskAttemptImpl中,其信息与资源本地性相关;

4 总结

HADOOP的机架感知功能,除了对HDFS的数据的副本有关之外,对YARN的NodeManager注册及Container的资源分发也有着密切的关系。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
Java-JDK动态代理(AOP)
使用JDK的反射机制,创建对象的能力,创建的时代理类的对象.而不用我们创建类的文件.
Java架构师必看
2021/05/14
2760
Java-JDK动态代理(AOP)
Feign原理 (图解)_feign原理
从上图可以看到,Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的 Request 请求。通过Feign以及JAVA的动态代理机制,使得Java 开发人员,可以不用通过HTTP框架去封装HTTP请求报文的方式,完成远程服务的HTTP调用。
全栈程序员站长
2022/11/10
4.3K0
Feign原理 (图解)_feign原理
SpringCloud原理之feign
前面一节我们学习了一下eureka,我们来回顾一下,首先它是一个cs架构,分为客户端和服务端,
用户9927510
2022/07/29
6500
SpringCloud原理之feign
Spring Cloud Feign工作原理、负载均衡及使用示例
Feign 是一个开源的Java HTTP客户端框架,主要用于简化服务间的HTTP调用,特别是针对微服务架构中的服务间通信。它允许开发者采用声明式的方式来定义HTTP请求,即将HTTP请求抽象成Java接口的方法调用,从而让服务间的调用看起来像是在调用本地方法一样简洁易懂。
用户7353950
2024/04/24
1.1K0
Spring Cloud Feign工作原理、负载均衡及使用示例
Feign 体系架构解析
正所谓麻雀虽小五脏俱全,HTTP 调用看着简单,实则下面隐藏的是一套非常复杂的流程。
程序员波特
2024/01/29
1940
Feign 体系架构解析
10000字 | 深入理解 OpenFeign 的架构原理
上次我们深入讲解了 Ribbon 的架构原理,这次我们再来看下 Feign 远程调用的架构原理。
悟空聊架构
2022/05/13
2.4K0
10000字 | 深入理解 OpenFeign 的架构原理
简单理解Feign的原理与使用
Spring Cloud 常见的集成方式是使用Feign+Ribbon技术来完成服务间远程调用及负载均衡的,如下图
ha_lydms
2023/08/09
8560
简单理解Feign的原理与使用
程序员不可不学的REST服务集成,Feign实现REST调用?
Feign 是 一 个 声 明 式 的 Web Service 客 户 端 , 它 使 得 编 写 WebService客户端更为容易。Feign受到Retrofit、JAXRS2.0、WebSocket的影响,采用声明式的API调用模式。
愿天堂没有BUG
2022/10/28
7920
程序员不可不学的REST服务集成,Feign实现REST调用?
spring cloud服务间调用之feign
在微服务架构盛行的年代,我们将一个大型的系统,拆解成各个服务,要完成一个业务逻辑,就可能需要,调用不同服务。比如订单服务调用会员服务。当然我们可以使用JDK自带的URLConnection,或者Apache的Http Client来调用,但是最为优雅的使用feign。
丁D
2022/08/12
9820
spring cloud服务间调用之feign
花一个周末,掌握 SpringCloud OpenFeign 核心原理
现在的微服务在互联网圈子里应用已经相关广泛了,SpringCloud 是微服务领域当之无愧的 "头牌"
Java识堂
2021/08/05
8.1K0
花一个周末,掌握 SpringCloud OpenFeign 核心原理
Feign的核心功能(三)
Feign支持通过集成Ribbon和Eureka来实现负载均衡和服务发现的功能。Ribbon是一个客户端负载均衡器,它可以根据不同的负载均衡算法来选择要调用的服务实例。Eureka是一个服务发现组件,它可以帮助我们动态地发现和注册服务实例,以实现服务的动态扩缩容和高可用性。
堕落飞鸟
2023/04/07
3220
SpringCloudRPC远程调用核心原理:Feign远程调用的执行流程
由于Feign中生成RPC接口JDK动态代理实例涉及的InvocationHandler调用处理器有多种,导致Feign远程调用的执行流程稍微有所区别,但是远程调用执行流程的主要步骤是一致的。这里主要介绍与两类InvocationHandler调用处理器相关的RPC执行流程:
愿天堂没有BUG
2022/10/31
1.5K0
SpringCloudRPC远程调用核心原理:Feign远程调用的执行流程
Feign的工作原理
Feign是一个伪Java Http 客户端,Feign 不做任何的请求处理。Feign 通过处理注解生成Request模板,从而简化了Http API 的开发。开发人员可以使用注解的方式定制Request API模板。
全栈程序员站长
2022/11/09
6580
Feign的工作原理
万字+33张图探秘OpenFeign核心架构原理
在很久之前,我写过两篇关于OpenFeign和Ribbon这两个SpringCloud核心组件架构原理的文章
三友的java日记
2024/02/29
1.4K0
万字+33张图探秘OpenFeign核心架构原理
你都用过SpringCloud的哪些组件,它们的原理是什么?
看到文章的题目了吗?就是这么抽象和笼统的一个问题,确实是我面试中真实被问到的,某共享货车平台的真实面试问题。 SpringCloud确实是用过,但是那是三四年前了,那个时候SpringCloud刚开始流行没多久,我们技术总监让我们调研一下,然后算上我在内的三个同事就一人买了一本SpringCloud的书籍,开始看,开始研究,正好那个时候DDD也比较火,然后我们就一边研究的SpringCloud一边按照DDD的模型搭建自己的项目。 但是这个项目最后做了三个月,才完成了一期。后面二期还没开始,我就撤了。所以SpringCloud总共的使用时间就两三个月,所以对这部分知识掌握的并不扎实,而且入职了新公司之后,都是使用公司自己封装的框架,也已经三年没有用过SpringCloud了,这次是要面试换工作了,所以决定将这方面的知识,总结一下。
纪莫
2021/01/21
7420
配置Spring Cloud Feign(一)
Spring Cloud Feign是一个声明式的HTTP客户端,它简化了使用HTTP客户端调用RESTful API的过程。使用Spring Cloud Feign,我们可以将RESTful API的调用看做是一个普通的方法调用,而不需要关心具体的HTTP请求和响应的细节。
堕落飞鸟
2023/04/07
3820
Feign:简化微服务通信的利器
Feign 是一个声明式、模板化的 HTTP 客户端,它简化了编写 Web 服务客户端的过程。它的主要目的是使 HTTP API 客户端的开发变得更加简单和直观。Feign 的设计理念是将 HTTP 客户端的细节隐藏在背后,使开发者可以专注于定义与服务端通信的接口而无需关注底层的实现细节。
繁依Fanyi
2024/05/13
6510
面试系列之-Spring Cloud Feign
根据传入的Bean对象和注解信息,从中提取出相应的值,来构造Http Request 对象;
用户4283147
2023/11/20
3600
面试系列之-Spring Cloud Feign
Feign源码解析4:调用过程
前面几篇分析了Feign的初始化过程,历经艰难,可算是把@FeignClient注解的接口对应的代理对象给创建出来了。今天看下在实际Feign调用过程中的一些源码细节。
低级知识传播者
2024/01/17
4260
Feign源码解析4:调用过程
SpringCloudRPC远程调用核心原理:FeignRPC动态代理实例创建流程
首先回顾一下Feign的整体运作流程。Feign英文直译为假装/装作,也就是说Feign是一个伪客户端,即它不做任何的HTTP请求处理。
愿天堂没有BUG
2022/10/31
8600
SpringCloudRPC远程调用核心原理:FeignRPC动态代理实例创建流程
相关推荐
Java-JDK动态代理(AOP)
更多 >
目录
  • 1 前言
    • 1.1 Hadoop机架感知功能对于HDFS
    • 1.2 Hadoop机架感知功能对于YARN
  • 2 启用Hadoop机架感知功能
    • 2.1 相关配置
    • 2.2 功能的启用
      • 2.2.1 脚本的编写
  • 3 YARN机架感知的源码分析
    • 3.1 初始化过程
    • 3.2 获取主机与机架的相应关系
      • 3.2.1 建立主机名与机架的对应关系
      • 3.2.2 从缓存中获取主机名对应机架信息
      • 3.2.3 从脚本中解析主机对应的机架信息
    • 3.3 主机与机架信息的调用
  • 4 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档