更新时间:2022-12-14 GMT+08:00

配置HDFS NodeLabel

配置场景

用户需要通过数据特征灵活配置HDFS文件数据块的存储节点。通过设置HDFS目录/文件对应一个标签表达式,同时设置每个Datanode对应一个或多个标签,从而给文件的数据块存储指定了特定范围的Datanode。

当使用基于标签的数据块摆放策略,为指定的文件选择DataNode节点进行存放时,会根据文件的标签表达式选择出Datanode节点范围,然后在这些Datanode节点范围内,选择出合适的存放节点。

  • 场景1 DataNodes分区场景。

    场景说明:

    用户需要让不同的应用数据运行在不同的节点,分开管理,就可以通过标签表达式,来实现不同业务的分离,指定业务存放到对应的节点上。

    通过配置NodeLabel特性使得:

    • /HBase下的数据存储在DN1、DN2、DN3、DN4节点上。
    • /Spark下的数据存储在DN5、DN6、DN7、DN8节点上。
    图1 DataNode分区场景
    • 通过hdfs nodelabel -setLabelExpression -expression 'LabelA[fallback=NONE]' -path /Hbase命令,给Hbase目录设置表达式。从图1中可知,“/Hbase”文件的数据块副本会被放置在有LabelA标签的节点上,即DN1、DN2、DN3、DN4。同理,通过hdfs nodelabel -setLabelExpression -expression 'LabelB[fallback=NONE]' -path /Spark命令,给Spark目录设置表达式。在“/Spark”目录下文件对应的数据块副本只能放置到LabelB标签上的节点,如DN5、DN6、DN7、DN8。
    • 设置数据节点的标签参考配置描述
    • 如果同一个集群上存在多个机架,每个标签下最好有多个机架的datanodes,以确保数据块摆放的可靠性。
  • 场景2 多机架下指定副本位置场景

    场景说明:

    在异构集群中,客户需要分配一些特定的具有高可靠性的节点用以存放重要的商业数据,可以通过标签表达式指定副本位置,指定文件数据块的其中一个副本存放到高可靠性的节点上。

    “/data”目录下的数据块,默认三副本情况下,其中至少有一个副本会被存放到RACK1或RACK2机架的节点上(RACK1和RACK2机架的节点为高可靠性节点),另外两个副本会被分别存放到RACK3和RACK4机架的节点上。

    图2 场景样例

    通过 hdfs nodelabel -setLabelExpression -expression 'LabelA||LabelB[fallback=NONE],LabelC,LabelD' -path /data命令给“/data”目录设置表达式。

    当向“/data”目录下写数据时,至少有一个数据块副本存放在LabelA或者LabelB标签的节点中,剩余的两个数据块副本会被存放在有LabelC和LabelD标签的节点上。

配置描述

  • Datanode节点标签配置

    请参考修改集群服务配置参数,进入HDFS的“全部配置”页面,在搜索框中输入参数名称。

    表1 参数说明

    参数

    描述

    默认值

    dfs.block.replicator.classname

    配置HDFS的DataNode原则策略。

    如果需要开启NodeLabeNodel功能,需要将该值设置为org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithNodeLabel。

    org.apache.hadoop.hdfs.server.blockmanagement.AvailableSpaceBlockPlacementPolicy

    host2tags

    配置DataNode主机与标签的对应关系。

    主机名称支持配置IP扩展表达式(如192.168.1.[1-128]或者192.168.[2-3].[1-128],且IP必须为业务IP),或者为前后加上 / 的主机名的正则表达式(如/datanode-[123]/或者/datanode-\d{2}/)。标签配置名称不允许包含 = / \ 字符。【注意】配置IP时必须是业务IP。

    -

    • host2tags配置项内容详细说明:

      假如有一套集群,有20个Datanode:dn-1到dn-20,对应的IP地址为10.1.120.1到10.1.120.20,host2tags配置文件内容可以使用如下的表示方式。

      主机名正则表达式

      “/dn-\d/ = label-1”表示dn-1到dn-9对应的标签为label-1,即dn-1 = label-1,dn-2 = label-1,...dn-9 = label-1。

      “/dn-((1[0-9]$)|(20$))/ = label-2”表示dn-10到dn-20对应的标签为label-2,即dn-10 = label-2,dn-11 = label-2,...dn-20 = label-2。

      IP地址范围表示方式

      “10.1.120.[1-9] = label-1”表示10.1.120.1到10.1.120.9对应的标签为label-1,即10.1.120.1 = label-1,10.1.120.2 = label-1,...10.1.120.9 = label-1。

      “10.1.120.[10-20] = label-2”表示10.1.120.10到10.1.120.20对应的标签为label-2,即10.1.120.10 = label-2,10.1.120.11 = label-2,...10.1.120.20 = label-2。

    • 基于标签的数据块摆放策略支持扩容减容场景:

      当集群中新增加DataNode节点时,如果该DataNode对应的IP匹配host2tags配置项中的IP地址范围,或者该DataNode的主机名匹配host2tags配置项中的主机名正则表达式,则该DataNode节点会被设置成对应的标签。

      例如“host2tags”配置值为10.1.120.[1-9] = label-1,而当前集群只有10.1.120.1到10.1.120.3三个数据节点。进行扩容后,又添加了10.1.120.4这个数据节点,则该数据节点会被设置成label-1的标签;如果10.1.120.3这个数据节点被删除或者退出服务后,数据块不会再被分配到该节点上。

  • 设置目录/文件的标签表达式
    • 在HDFS参数配置页面配置“path2expression”,配置HDFS目录与标签的对应关系。当配置的HDFS目录不存在时,也可以配置成功,新建不存在的同名目录,已设置的标签对应关系将在30分钟之内被继承。设置了标签的目录被删除后,新增一个同名目录,原有的对应关系也将在30分钟之内被继承。
    • 命令行设置方式请参考hdfs nodelabel -setLabelExpression命令。
    • Java API设置方式通过NodeLabelFileSystem实例化对象调用setLabelExpression(String src, String labelExpression)方法。src为HDFS上的目录或文件路径,“labelExpression”为标签表达式。
  • 开启NodeLabel特性后,可以通过命令hdfs nodelabel -listNodeLabels查看每个Datanode的标签信息。

块副本位置选择

Nodelabel支持对各个副本的摆放采用不同的策略,如表达式“label-1,label-2,label-3”,表示3个副本分别放到含有label-1、label-2、label-3的DataNode中,不同的副本策略用逗号分隔。

如果label-1,希望放2个副本,可以这样设置表达式:“label-1[replica=2],label-2,label-3”。这种情况下,如果默认副本数是3,则会选择2个带有label-1和一个label-2的节点;如果默认副本数是4,会选择2个带有label-1、一个label-2以及一个label-3的节点。可以注意到,副本数是从左到右依次满足各个副本策略的,但也有副本数超过表达式表述的情况,当默认副本数为5时,多出来的一个副本会放到最后一个节点中,也就是label-3的节点里。

当启用ACLs功能并且用户无权访问表达式中使用的标签时,将不会为副本选择属于该标签的DataNode。

多余块副本删除选择

如果块副本数超过参数“dfs.replication”值(即用户指定的文件副本数),hdfs会删除多余块副本来保证集群资源利用率。

删除规则如下:

  • 优先删除不满足任何表达式的副本。

    示例:文件默认副本数为3

    /test标签表达式为“LA[replica=1],LB[replica=1],LC[replica=1]”,

    /test文件副本分布的四个节点(D1~D4)以及对应标签(LA~LD):

    D1:LA
    D2:LB
    D3:LC
    D4:LD

    则选择删除D4节点上的副本块。

  • 如果所有副本都满足表达式,删除多于表达式指定的数量的副本。

    示例:文件默认副本数为3

    /test标签表达式为“LA[replica=1],LB[replica=1],LC[replica=1]”,

    /test文件副本分布的四个节点以及对应标签:

    D1:LA
    D2:LA
    D3:LB
    D4:LC

    则选择删除D1或者D2上的副本块。

  • 如果文件所有者或文件所有者的组不能访问某个标签,则优先删除映射到该标签的DataNode中的副本。

基于标签的数据块摆放策略样例

假如有一套集群,有六个DataNode:dn-1,dn-2,dn-3,dn-4,dn-5以及dn-6,对应的IP为10.1.120.[1-6]。有六个目录需要配置标签表达式,Block默认备份数为3。

  • 下面给出3种DataNode标签信息在“host2labels”文件中的表示方式,其作用是一样的。
    • 主机名正则表达式
      /dn-[1456]/ = label-1,label-2
      /dn-[26]/ = label-1,label-3
      /dn-[3456]/ = label-1,label-4
      /dn-5/ = label-5
    • IP地址范围表示方式
      10.1.120.[1-6] = label-1
      10.1.120.1 = label-2
      10.1.120.2 = label-3
      10.1.120.[3-6] = label-4
      10.1.120.[4-6] = label-2
      10.1.120.5 = label-5
      10.1.120.6 = label-3
    • 普通的主机名表达式
      /dn-1/ = label-1, label-2
      /dn-2/ = label-1, label-3
      /dn-3/ = label-1, label-4
      /dn-4/ = label-1, label-2, label-4
      /dn-5/ = label-1, label-2, label-4, label-5
      /dn-6/ = label-1, label-2, label-3, label-4
  • 目录的标签表达式设置结果如下:
    /dir1 = label-1
    /dir2 = label-1 && label-3
    /dir3 = label-2 || label-4[replica=2]
    /dir4 = (label-2 || label-3) && label-4
    /dir5 = !label-1
    /sdir2.txt = label-1 && label-3[replica=3,fallback=NONE]
    /dir6 = label-4[replica=2],label-2

    标签表达式设置方式请参考hdfs nodelabel -setLabelExpression命令。

    文件的数据块存放结果如下:

    • “/dir1”目录下文件的数据块可存放在dn-1,dn-2,dn-3,dn-4,dn-5和dn-6六个节点中的任意一个。
    • “/dir2”目录下文件的数据块可存放在dn-2和dn-6节点上。Block默认备份数为3,表达式只匹配了两个DataNode节点,第三个副本会在集群上剩余的节点中选择一个DataNode节点存放。
    • “/dir3”目录下文件的数据块可存放在dn-1,dn-3,dn-4,dn-5和dn-6中的任意三个节点上。
    • “/dir4”目录下文件的数据块可存放在dn-4,dn-5和dn-6。
    • “/dir5”目录下文件的数据块没有匹配到任何一个DataNode,会从整个集群中任意选择三个节点存放(和默认选块策略行为一致)。
    • “/sdir2.txt”文件的数据块,两个副本存放在dn-2和dn-6节点上,虽然还缺失一个备份节点,但由于使用了fallback=NONE参数,所以只存放两个备份。
    • “/dir6”目录下文件的数据块在具备label-4的节点中选择2个节点(dn-3 -- dn-6),然后在label-2中选择一个节点,如果用户指定“/dir6”下文件副本数大于3,则多出来的副本均在label-2。

使用限制

配置文件中,“key”“value”是以“=”、“:”及空白字符作为分隔的。因此,“key”对应的主机名中间请勿包含以上字符,否则会被误认为分隔符。