• 聊聊Ozone的Topology Awareness


    前言


    众所周知,在大规模分布式存储系统中,数据往往通过多副本的形式来保持其可用性。但是多副本如何进行位置放置又是一项值得深挖的领域。至少我们总不能将所有副本都放在一台机器这样的极端情况。对于副本数据的放置,其实涉及到的考量因素还是比较多的,副本放置过于分散化,网络traffic开销就打了,但是过于靠拢增加本地性读呢,冗余性又会受到影响,例如某个rack机器突然故障等等。这里我们将这类的问题称为Topology Awareness问题,本文我们来聊聊Ozone的Topology Awareness方面的内容。

    HDFS的Topology Awareness


    笔者第一次了解到Topology Awareness是在学习HDFS Block placement的时候,HDFS遵守3副本块按照,同rack,非同rack的三副本放置策略原则来达到数据高可用性的目的。这样的放置策略当然没有什么大的问题,它能容忍一台机器或一个rack不可用导致实际数据不可用的情况。

    所以在这里,管理员配置什么样的topology规则就显得十分得重要了。我们可以使用最简单的规则,比如,用物理rack作为逻辑的topology位置rack。如果我们不配置任何的topology的规则,则所有机器的网络位置将会变成default-rack,default-rack并不是一个好的设置。

    HDFS Topology的层级,距离定义问题


    管理员根据集群节点的实际物理位置,给出对于topology location位置,这并不是难事。但问题来了,有的时候我们需要构建出更加复杂的topology结构,而不仅仅是data center–>rack—>node这样的三级结构。

    比如说,我们还想在rack层再做一个group,变成4级结构,或者可能在group层上在做个别属性划分。目前HDFS的Topology还不支持5级层级,group层已经有对应的实现类。因此在layer层的自定义上,HDFS的Topology Awareness还没有达到足够灵活的程度。

    /dc
    |
    /rackgroup
    |
    /rack
    |
    /node

    另外一点,Topology多层级的划分一方面是为了表明各节点的物理归属位置的不同,还有一点是不同层级的distance不同。这个distance可理解为数据网络传输的开销,跨rack节点间的数据传输比同rack间的节点数据传输的慢,前者的distance就长一点。所以在这里,我们可以给不同layer直接定义不同的distance cost。比如/dc到/rack是2,/rack到/node是1。

    在HDFS现有的Topology规则下,没有自定义distance cost的概念,不同layer间的距离是等价的,可以理解为都是1个单位长度。

    为什么这里我们这么强调network distance cost的概念呢?因为这里会涉及到最近距离的数据read的问题。对于客户端的数据读操作来说,选择与其最近的节点去读数据显然是一种更优的策略方法。

    Ozone同样作为数据存储系统,它在HDFS Topology Awareness以上提到的2点不足之处都做了进一步地完善和改进,使之变成了更加灵活的Topology Awareness。

    Ozone的Topology Awareness的配置使用


    Ozone的Topology Awareness的核心思想和HDFS 类似,同样基于的是同rack,不同rack的多副本放置策略。这里重点谈谈它的自定义layer和distance cost的设置。

    相比于HDFS为了支持不同layer,通过定义新的实现子类这样略显笨重的方式,Ozone则定义了node schema的概念,来支持用户自定义的topology。

    在一个node schema中,它包含了node的类型,这里的类型为以下3类:

    • ROOT(“Root”, NetConstants.INNER_NODE_COST_DEFAULT),
    • INNER_NODE(“InnerNode”, NetConstants.INNER_NODE_COST_DEFAULT),
    • LEAF_NODE(“Leaf”, NetConstants.NODE_COST_DEFAULT);

    然后后面属性是其cost值。

    然后这些被加载好的node schema被NodeSchemaManager以list的方式维护,按照深度顺序,从上往下。

    这里schema的定义由外部传入的topology文件决定,以下为一份自定义的topology文件,深度为4,相当于HDFS的NetworkTopologyWithNodeGroup类。

    <?xml version="1.0"?>
    <configuration>
        <layoutversion>1</layoutversion>
        <layers>
            <layer id="datacenter">
                <prefix></prefix>
                <cost>1</cost>
                <type>Root</type>
            </layer>
            <layer id="rack">
                <prefix>rack</prefix>
                <cost>1</cost>
                <type>InnerNode</type>
                <default>/default-rack</default>
            </layer>
            <layer id="node">
                <prefix></prefix>
                <cost>0</cost>
                <type>Leaf</type>
            </layer>
        </layers>
        <topology>
            <path>/datacenter/rack/node</path>
            <!-- When this field is true, each InnerNode layer should has its prefix defined with not empty value,
             otherwise the content is not valid. Default value is false.
             -->
            <enforceprefix>false</enforceprefix>
        </topology>
    </configuration>
    

    然后我们再配上topology mapping,用来指定各节点的topology 位置,按照上述的schema模式,layer层深度为4。上面cost的配置取决于实际物理cost开销,进行配置。

     hostrack file:
     xx(lyq-s2xx)    /dc1/rack1
     xx(lyq-s4xx)    /dc1/rack2
     xx(lyq-s3xx)    /dc2/rack1
     xx(lyq-s1xx)    /dc2/rack2
    

    这里的dc相当于rack上的group。然后配置上Ozone topology相关配置项,

    <property>
       <name>ozone.scm.network.topology.schema.file</name>
       <value>/home/hdfs/apache/ozone/etc/hadoop/ozone-topology-default.xml</value>
    </property>
    
    <property>
      <name>net.topology.node.switch.mapping.impl</name>
      <value>org.apache.hadoop.net.ScriptBasedMapping</value>
    </property>
    
    <property>
      <name>net.topology.script.file.name</name>
      <value>/home/hdfs/apache/ozone/etc/hadoop/topology.py</value>
    </property>
    

    python解析脚本,

    import sys
    import os
    import pwd
    sys.argv.pop(0)
    rack_dic = {}
    try:
       with open("/home/hdfs/apache/ozone/etc/hadoop/hostrack") as f:
            for line in f:
               (key, val) = line.split()
               rack_dic[key] = val
       for ip in sys.argv:
            print '{0}'.format(rack_dic[ip])
    except Exception,e:
        print "/default-rack"
    

    配置完毕后,我们进行scm的重启,然后执行命令printTopology的命令,我们可以看到各个节点已经加载了最新的topology位置,

    [hdfs@lyq hadoop]$ ~/apache/ozone/bin/ozone scmcli printTopology
    State = HEALTHY
     xx(lyq-s2xx)    /dc1/rack1
     xx(lyq-s4xx)    /dc1/rack2
     xx(lyq-s3xx)    /dc2/rack1
     xx(lyq-s1xx)    /dc2/rack2
    

    倘若用户传入了一个层级不对的topology mapping,将会导致类似如下的节点注册错误,

    2019-12-18 07:56:58,579 WARN org.apache.hadoop.ipc.Server: IPC Server handler 1 on 9861, call Call#9916 Retry#0 org.apache.hadoop.ozone.protocol.StorageContainerDatanodeProtocol.submitRequest from xx.xx.xx.xx:40568
    org.apache.hadoop.hdds.scm.net.NetworkTopology$InvalidTopologyException: Failed to add /dc2/rack2/0d98dfab-9d34-46c3-93fd-6b64b65ff543: Its path depth is not 3
    	at org.apache.hadoop.hdds.scm.net.NetworkTopologyImpl.add(NetworkTopologyImpl.java:100)
    	at org.apache.hadoop.hdds.scm.node.SCMNodeManager.register(SCMNodeManager.java:263)
    	at org.apache.hadoop.hdds.scm.server.SCMDatanodeProtocolServer.register(SCMDatanodeProtocolServer.java:225)
    	at org.apache.hadoop.ozone.protocolPB.StorageContainerDatanodeProtocolServerSideTranslatorPB.register(StorageContainerDatanodeProtocolServerSideTranslatorPB.java:69)
    	at org.apache.hadoop.ozone.protocolPB.StorageContainerDatanodeProtocolServerSideTranslatorPB.processMessage(StorageContainerDatanodeProtocolServerSideTranslatorPB.java:104)
    	at org.apache.hadoop.hdds.server.OzoneProtocolMessageDispatcher.processRequest(OzoneProtocolMessageDispatcher.java:72)
    	at org.apache.hadoop.ozone.protocolPB.StorageContainerDatanodeProtocolServerSideTranslatorPB.submitRequest(StorageContainerDatanodeProtocolServerSideTranslatorPB.java:77)
    

    Ozone Topology Awareness的用途


    Ozone topology awareness配置使用完毕之后,它将会在哪些地方起到作用呢?主要在以下2个方面:

    • 第一,在Container做replication的时候,用以选择符合topology awareness条件的节点做Container级别的replication。
    • 第二,Container选取Pipeline时,Pipeline内部节点的构成需要满足topology awareness规则。

    以上,就是本文今天所谈论的关于Ozone系统内的Topology Awareness相关的内容,和HDFS的Topology Awareness类似但灵活许多。

    引用


    [1].https://issues.apache.org/jira/browse/HDDS-698 . Support Topology Awareness for Ozone

  • 相关阅读:
    Java实现“睡排序”——线程池Executors的使用
    浅谈HashMap与线程安全 (JDK1.8)
    Ubuntu 16 Java Develop环境快速搭建
    Spring Boot在反序列化过程中:jackson.databind.exc.InvalidDefinitionException cannot deserialize from Object value
    Java 8 – Map排序
    vue指令优化网络图片加载速度
    如何实现小于12px的字体效果
    两种以上方式实现已知或者未知宽度的垂直水平居中
    C# winform窗体间传值(使用委托或事件)
    C#栈Stack的使用
  • 原文地址:https://www.cnblogs.com/bianqi/p/12183498.html
Copyright © 2020-2023  润新知