
# 配置HDFS文件目录标签策略（NodeLabel）
#### 操作场景
用户需要通过数据特征灵活配置HDFS文件数据块的存储节点。通过设置HDFS目录/文件对应一个标签表达式，同时设置每个DataNode对应一个或多个标签，从而给文件的数据块存储指定了特定范围的DataNode。
当使用基于标签的数据块摆放策略，为指定的文件选择DataNode节点进行存放时，会根据文件的标签表达式选择出DataNode节点范围，然后在这些DataNode节点范围内，选择出合适的存放节点。
在调整HDFS数据块复制策略时，必须充分考虑以下因素：
- 要保证数据的可靠性，避免出现数据丢失的情况。
- 尽量减少跨机架的数据传输，以提高传输效率。
- 考虑负载均衡问题，防止某些节点负载过高。
- 进行充分的测试，确保自定义策略能够正常工作。
通过合理配置数据块复制策略，可以让HDFS更好地适应不同的应用场景，从而提升整个集群的性能和可靠性。
- **场景1 DataNodes分区场景**
  用户需要让不同的应用数据运行在不同的节点，分开管理，就可以通过标签表达式，来实现不同业务的分离，指定业务存放到对应的节点上。
  通过配置NodeLabel特性使得：
  - /HBase下的数据存储在DN1、DN2、DN3、DN4节点上。
  
  - /Spark下的数据存储在DN5、DN6、DN7、DN8节点上。
  
  
  图1DataNode分区场景   
  ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_image_0265698454.png)
  - 通过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。
    
  
  - 设置数据节点的标签参考[配置DataNode节点数据块复制策略]。
  
  - 如果同一个集群上存在多个机架，每个标签下可以有多个机架的DataNodes，以确保数据块摆放的可靠性。
   

- **场景2 多机架下指定副本位置场景**
  在异构集群中，需要分配一些特定的具有高可靠性的节点用以存放重要的商业数据，可以通过标签表达式指定副本位置，指定文件数据块的其中一个副本存放到高可靠性的节点上。
  "/data"目录下的数据块，默认三副本情况下，其中至少有一个副本会被存放到RACK1或RACK2机架的节点上（RACK1和RACK2机架的节点为高可靠性节点），另外两个副本会被分别存放到RACK3和RACK4机架的节点上。
  图2场景样例   
  ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_image_0265698455.png)
  - 通过hdfs nodelabel -setLabelExpression -expression 'LabelA||LabelB[fallback=NONE],LabelC,LabelD' -path /data命令给"/data"目录设置表达式。
  
  - 当向"/data"目录下写数据时，至少有一个数据块副本存放在LabelA或者LabelB标签的节点中，剩余的两个数据块副本会被存放在有LabelC和LabelD标签的节点上。
   
 
#### 约束与限制
- 本章节适用于MRS 3.x及后续版本。
- 配置文件中，"key"、"value"是以"="、":"及空白字符作为分隔的。因此，"key"对应的主机名中间请勿包含以上字符，否则会被误认为分隔符。
 
 #### 配置DataNode节点数据块复制策略
1. 登录FusionInsight Manager。 
   登录集群Manager具体操作，请参考[访问MRS集群Manager](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0128.html)。
   
   
2. 选择"集群 \> 服务 \> HDFS \> 配置 \> 全部配置"。
3. 搜索以下参数名称，并根据需要修改参数值。 
   表1参数说明 
   | **参数**                         | **描述**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | **配置示例**                                                                        |
   |:---|:---|:---|
   | dfs.block.replicator.classname | 配置HDFS的DataNode副本存储策略，如果需要开启NodeLabe功能，需要将该值设置为org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithNodeLabel。 参数取值及含义如下： - org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithNodeLabel：开启NodeLabe功能，基于节点标签的存储策略。  - org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyDefault：使用Hadoop标准副本存储策略。  - org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithRackGroup：基于机架组信息的存储策略。需要同步设置"dfs.use.dfs.network.topology"配置项的值为"false"，以及"net.topology.impl"配置项的值为"org.apache.hadoop.net.NetworkTopologyWithRackGroup"。  - org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithNodeGroup：基于节点组信息的存储策略。  - org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithNonAffinityNodeGroup：根据非亲和性节点组来决定块的放置位置，避免将副本放在同一组节点中。  - org.apache.hadoop.hdfs.server.blockmanagement.AvailableSpaceBlockPlacementPolicy：优先选择可用空间较多的节点来放置块。  - org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyRackFaultTolerant：确保块的副本分布在不同的机架上，提高机架级别的容错能力。                                                                                                                                                                                                                                                                                                                                                                                                                                 | org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithNodeLabel |
   | host2tags                      | 配置DataNode主机与标签的对应关系。 - 主机名称支持配置IP扩展表达式（如192.168.1.\[1-128\]或者192.168.\[2-3\].\[1-128\]），或者为前后加上"/"的主机名的正则表达式（如/datanode-\[123\]/或者/datanode-\\d{2}/）。  - 标签配置名称不允许包含= / \\字符。  - 配置样例： 例如某MRS集群有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这个数据节点被删除或者退出服务后，数据块不会再被分配到该节点上。    | -                                                                               |
      
   
   
4. 单击"保存"，在"实例"页面查看是否有配置过期的实例，如果有，则勾选配置过期的实例，选择"更多 \> 重启实例"，重启完成后配置生效。
5. 配置完成后，可以参考[使用HDFS客户端](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_1663.html#mrs_01_1663__zh-cn_topic_0265698398_s729d2c48e7354c7bb15884e152e37570)登录HDFS客户端，通过以下命令查看每个DataNode的标签信息。
   
   ```
   hdfs nodelabel -listNodeLabels [-all] [-node <node_name>]
   ```
   - -all：显示所有标签组，包括未关联任何节点的标签（默认仅显示已关联节点的标签）。
   
   - -node \<name\>：查看指定节点（主机名或 IP）已分配的标签组。
   
   
   
   
 
#### 设置HDFS目录/文件的标签表达式
- **通过Manager配置**
  1. 登录FusionInsight Manager。 登录集群Manager具体操作，请参考[访问MRS集群Manager](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0128.html)。
     
  
  2. 选择"集群 \> 服务 \> HDFS \> 配置 \> 全部配置"。
  
  3. 搜索以下参数名称，并根据需要修改参数值。
     
     | **参数**          | **描述**                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
     |:---|:---|
     | path2expression | 配置HDFS目录与标签的对应关系。 - 当配置的HDFS目录不存在时，也可以配置成功，新建不存在的同名目录，已设置的标签对应关系将在30分钟之内被继承。  - 设置了标签的目录被删除后，重新增加一个同名目录，原有的对应关系也将在30分钟之内被继承。   |
        
     
  
  4. 单击"保存"使配置生效，无需重启HDFS服务。
  
  5. 配置完成后，可以参考[通过命令行配置]登录HDFS客户端后，执行以下命令查看目录的标签是否生效。
     ```
     hdfs nodelabel -listLabelExpression -path <path>
     ```
     其中，\<path\>为需要查询的HDFS目录。
     
   

- **通过集群客户端配置**
  1. 安装客户端，如果已安装则跳过。 例如安装目录为"/opt/client"，以下操作的客户端目录只是举例，请根据实际安装目录修改。
     下载并安装集群客户端的具体操作，请参考[安装MRS集群客户端](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0089.html)。
     
  
  2. 以客户端安装用户，登录安装客户端的节点。
  
  3. 执行以下命令，切换到客户端安装目录，例如"/opt/client"。
     ```
     cd /opt/client
     ```
     
  
  4. 执行以下命令配置环境变量。
     ```
     source bigdata_env
     ```
     
  
  5. 如果集群为安全模式，执行以下命令进行用户认证。普通模式集群无需执行用户认证。
     ```
     kinit 组件业务用户
     ```
     
  
  6. 执行以下命令设置目录/文件的标签表达式。
     ```
     hdfs nodelabel -setLabelExpression <expression> -add <label1,label2,...> 
     hdfs nodelabel -setLabelExpression <expression> -remove <label1,label2,...>
     ```
     - \<expression\>：节点匹配表达式，支持以下语法：
       - 主机名/IP：如host1.test.com或192.168.1.100。
       
       - 通配符：\*（匹配任意字符）、?（匹配单个字符），如 \*.test.com。
       
       - 正则表达式：用 \~ 开头，如 \~.\*\\.test\\.com。
        
     
     - -add：为匹配的节点添加标签。
     
     - -remove：从匹配的节点移除标签。
     
     
     例如，为data-node-\[1-5\]添加hot标签：
     ```
     hdfs nodelabel -setLabelExpression "data-node-[1-5]" -add hot
     ```
     
   
- **通过Java API方式配置**
  Java API设置方式通过NodeLabelFileSystem实例化对象调用setLabelExpression(String *src* , String labelExpression)方法。*src*为HDFS上的目录或文件路径，"labelExpression"为标签表达式。
  
 
#### 块副本位置选择说明
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"值（即用户指定的文件副本数，可以参考[修改集群服务配置参数](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_2125.html)进入HDFS服务全部配置页面，搜索对应参数查看），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中的副本。
 
#### 基于标签的数据块摆放策略样例
例如某MRS集群有六个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
  ```
  标签表达式设置方式请参考[通过命令行配置]。
  文件的数据块存放结果如下：
  - "/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。
   
 
#### 相关文档
- 在资源池场景下，通过NodeLabel特性将集群划分为两个资源池，YARN资源池的所有节点都被加入黑名单，任务一直处于运行状态，可以参考[YARN资源池的所有节点都被加入黑名单，任务一直处于运行状态](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_2083.html)进行处理。
- 关于更多NodeLabel详细介绍请参考[YARN Node Labels](https://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-site/NodeLabel.html)。
 
