HDFS源码解析---NetworkTopology

11 篇文章 4 订阅

        NetworkTopology 是common 包下的一个类,用来描述hadoop 集群的节点网络拓扑。在HDFS 中,这个类会在选DN 的场景下被使用。NetworkTopology将整个集群中的DN存储成了一个树状网络拓扑图, 表示一个具有树状网络拓扑结构的计算机集群, 一个集群可能由多个数据中心Data Center组成, 在这些数据中心分布着为计算需求而设置的很多计算机的机架Rack. InnerNode内部类, 表示数据中心/机架的转换器/或路由

        通常来说,一个DN 的拓扑一般是这样的结构 /region/az/idc/room/tor/rack/x,region 通常表示一个地区,az 是逻辑机房,包含多个idc,在idc 内部,通常包含多个房间,每个房间有不同的机柜,一个机柜包含很多机架,而DN (可以抽象为物理机)就放置在机架上。

        Node 接口定义了在网络拓扑中的每一个节点。每一个Node 在网络拓扑中应该有一个名称及其位置(使用类似文件路径的方式来定义), 例如一个Datanode名称为hostname:port,  并且该Datanode在数据中心dog里的orange机架上, 则这个Datanode在网络拓扑中的位置(网络地址)为/dog/orange.  

        NodeBase 实现了Node接口, 是一个最基本的结点的实现. 该类定义的属性都是与一个结点的基本属性信息相关的。假设DN节点的路径path=/a/b/c, 则节点名称name=c, 节点路径location=/a/b.  节点的 path 不需要定义, 由 location/name组成。按照NodeBase的实现, 子节点的location=父节点的path。

        下面来看InnerNode.getLoc()

        假设传入的loc=/a/b/c 表示在region=a,az=b,idc=c,这个方法需要从/a/b/c 这个idc 内选一个节点,当然,这个Node 同样是个树状结构。首先 /a/b/c normalize 后变成a/b/c

  /** Given a string representation of a node, return its reference
   * 
   * @param loc
   *          a path-like string representation of a node
   * @return a reference to the node; null if the node is not in the tree
   */
  public Node getNode(String loc) {
    netlock.readLock().lock();
    try {
      loc = NodeBase.normalize(loc);
      if (!NodeBase.ROOT.equals(loc))
        loc = loc.substring(1);
      return clusterMap.getLoc(loc);
    } finally {
      netlock.readLock().unlock();
    }
  }
    /** Given a node's string representation, return a reference to the node  参数loc说明了不会传递dn节点名称进来 */ 
    private Node getLoc(String loc) {
      if (loc == null || loc.length() == 0) return this;
            
      String[] path = loc.split(PATH_SEPARATOR_STR, 2);  	// 如果loc=r1/r2, path=[r1, r2]; 如果loc=r1/r2/r3, path=[r1, r2/r3]
      Node childnode = null;
      for(int i=0; i<children.size(); i++) {
        if (children.get(i).getName().equals(path[0])) {
          childnode = children.get(i);
        }
      }
      if (childnode == null) return null; 					// non-existing node
      if (path.length == 1) return childnode;
      if (childnode instanceof InnerNode) {
        return ((InnerNode)childnode).getLoc(path[1]);	// 递归调用
      } else {
        return null;
      }
    }

        第一次 path[0]=region=a 找到/ 下所有的子节点(假设只有/a)匹配上之后,childnode = /a,然后递归 /a .getLoc(b/d)
第二次 path[0]=az=b 找到/a 下所有子节点(假设只有/a/b)匹配上之后,childnode = /a/b 然后递归 /a/b. getLoc(d)
第三次 path[0]=idc=d 找到/a/b 下所有子节点(假设只有/a/b/d)匹配上之后,childnode = /a/b/d 此时path 长度=1,返回 childnode。

        这个返回值最后会作为chooseRandom 的入参,在这个节点下的所有节点中选一个DN 出来。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值