
# 配置HDFS DataNode数据均衡
#### 操作场景
HDFS集群可能出现DataNode节点间磁盘利用率不平衡的情况，比如集群中添加新数据节点的场景。如果HDFS出现数据不平衡的状况，可能导致多种问题，比如MapReduce应用程序无法很好地利用本地计算的优势、数据节点之间无法达到更好的网络带宽使用率或节点磁盘无法利用等等。所以MRS集群管理员需要定期检查并保持DataNode数据平衡。
HDFS提供了一个容量均衡程序Balancer。通过运行这个程序，可以使得HDFS集群达到一个平衡的状态，使各DataNode磁盘使用率与HDFS集群磁盘使用率的偏差不超过阈值。[图1]和[图2]分别是Balance前后DataNode的磁盘使用率变化。
图1执行均衡操作前DataNode的磁盘使用率   
![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_image_0000001086235566.png "点击放大")
图2执行均衡操作后DataNode的磁盘使用率   
![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_image_0265788156.png "点击放大")
均衡操作时间估算受两个因素影响：
1. 需要迁移的总数据量： 每个DataNode节点的数据量应大于（平均使用率-阈值）\*平均数据量，小于（平均使用率+阈值）\*平均数据量。若实际数据量小于最小值或大于最大值即存在不平衡，系统选择所有DataNode节点中偏差最多的数据量作为迁移的总数据量。
   
2. Balancer的迁移是按迭代（iteration）方式串行顺序处理的，每个iteration迁移数据量不超过10GB，每个iteration重新计算使用率的情况。
因此针对集群情况，可以大概估算每个iteration耗费的时间（可以通过执行Balancer的日志观察到每次iteration的时间），并用总数据量除以10GB估算任务执行时间。
由于按iteration处理，Balancer可以随时启动或者停止。
#### 约束与限制
- 本章节适用于MRS 3.x及后续版本。
- 执行Balance操作时会占用DataNode的网络带宽资源，请根据业务需求在维护期间执行任务。
- 默认使用带宽控制为20MB/s，如果重新设置带宽流量或加大数据量，Balance操作可能会对正在运行的业务产生影响。
 
#### 前提条件
已安装HDFS客户端。例如安装路径为"/opt/client"。
#### 配置Balance任务
1. 使用客户端安装用户登录客户端所在节点。执行命令切换到客户端安装目录，例如"/opt/client"。 
   如果集群为普通模式，需先执行**su - omm** 切换为**omm**用户。
   ```
   cd /opt/client
   ```
   
   
2. 执行以下命令配置环境变量。 
   ```
   source bigdata_env
   ```
   
   
3. 如果集群为安全模式，执行以下命令认证**hdfs** 身份，**hdfs** 用户默认密码为Hdfs@123。
   
   ```
   kinit hdfs
   ```
   
   
4. 是否调整带宽控制？ 
   - 是，执行[5]。
   
   - 否，执行[6]。
   
   
   
   
5. 执行以下命令，修改Balance的最大带宽，然后执行[6]。
   
   ```
   hdfs dfsadmin -setBalancerBandwidth <bandwidth in bytes per second>
   ```
   *\<bandwidth in bytes per second\>*表示带宽控制的数值，单位为字节。例如要设置带宽控制为20MB/s，对应值为20971520，完整命令为：
   ```
   hdfs dfsadmin -setBalancerBandwidth 20971520
   ```
   - Balance的最大带宽默认为20MB/s，适用于当前集群使用万兆网络，且有业务正在执行的场景。若没有足够的业务空闲时间窗用于Balance维护，可适当增加该值以缩短Balance时间，如增大到209715200（即200MB/s）。
   
   - 该参数需要根据组网实际情况进行调整，如果集群负载较高，可以改为209715200(200MB/s)；如果集群空闲，可以改为1073741824 (1GB/s)。
   
   - 如果DataNode节点的带宽无法达到指定的最大带宽，可以在FusionInsight Manager调大HDFS的参数"dfs.datanode.balance.max.concurrent.moves"取值，并重启HDFS服务。 "dfs.datanode.balance.max.concurrent.moves"该参数表示允许在DataNode上进行负载均衡的最大线程数。取值范围5\~1000。
     
   
   
   
   
6. 确认是否调整HDFS客户端内存上限。
   
   如果HDFS客户端内存上限较小，则在数据均衡过程中可能会报错"OutOfMemoryError"。
   - 是，执行以下操作调整，然后执行[7]。
     1. 执行以下命令，查看可用内存大小。
        ```
        free -h
        ```
        例如，执行后结果如下：
        ```
        total        used        free      shared  buff/cache   available
        Mem:           56Gi        36Gi       3.2Gi       6.2Gi        17Gi        10Gi
        Swap:            0B          0B          0B
        ```
        
     
     2. 执行以下命令修改文件。
        ```
        vim 客户端安装路径/HDFS/component_env
        ```
        根据实际情况，调整内存大小，例如调整堆内存最大值为1GB：
        ```
        CLIENT_GC_OPTS="-Xmx1G"
        ```
        
     
     3. 修改完成后执行如下命令刷新客户端配置，使之生效。
        ```
        source 客户端安装路径/bigdata_env
        ```
        
      
   
   - 否，执行[7]。
   
   
   
   
7. 执行以下命令，启动Balance任务。
   
   ```
   bash /opt/client/HDFS/hadoop/sbin/start-balancer.sh -threshold <threshold of balancer>
   ```
   **-threshold**表示HDFS数据达到平衡状态时DataNode磁盘使用率偏差值，各个DataNode节点磁盘的使用率和整体HDFS集群的磁盘空间平均使用率偏差小于此阈值时，系统认为HDFS集群已经达到了平衡的状态并结束Balance任务。
   例如，需要设置偏差率为5%，则执行：
   ```
   bash /opt/client/HDFS/hadoop/sbin/start-balancer.sh -threshold 5
   ```
   - "/opt/client"为客户端安装目录，具体请以实际路径替换。
   
   - 上述命令会在后台执行该任务，相关日志可以通过客户端安装目录"/opt/client/HDFS/hadoop/logs"下的hadoop-root-balancer-*主机名*.out查看。
   
   - 如果需要停止Balance任务，请执行以下命令：
     ```
     bash /opt/client/HDFS/hadoop/sbin/stop-balancer.sh
     ```
     
   
   - 如果只需要对部分节点进行数据均衡，可以在脚本上加上-include参数指定要移动的节点。具体参数使用方法，可通过命令行查看。 例如执行：
     ```
     bash /opt/client/HDFS/hadoop/sbin/start-balancer.sh -threshold 5 -include IP1,IP2,IP3
     ```
     
   
   - 如果该命令执行失败，在日志中看到的错误信息为"Failed to APPEND_FILE /system/balancer.id"，则需要执行如下命令强行删除"/system/balancer.id"，再次执行**start-balancer.sh** 脚本即可。
     ```
     hdfs dfs -rm -f /system/balancer.id
     ```
     
   
   
   
   
8. 用户在执行了[7]的脚本后，会在客户端安装目录"/opt/client/HDFS/hadoop/logs"目录下生成名为hadoop-root-balancer-*主机名* .out日志。打开该日志可以看到如下字段信息：
   
   - Time Stamp：时间戳
   
   - Bytes Already Moved：已经移动的字节数
   
   - Bytes Left To Move：待移动的字节数
   
   - Bytes Being Moved：正在移动的字节数
   
   
   日志出现"Balancing took *xxx* seconds"信息表示均衡操作已完成。
   
   
 
#### 设置自动执行Balance任务
1. 登录FusionInsight Manager。 
   登录集群Manager具体操作，请参考[访问MRS集群Manager](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0128.html)。
   
   
2. 选择"集群 \> 服务 \> HDFS \> 配置"，选择"全部配置"，搜索以下参数名并修改参数值。 
   表1参数解释 
   | 参数名                                    | 参数解释                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | 默认取值        |
   |:---|:---|:---|
   | dfs.balancer.auto.enable               | 是否启用自动执行Balance均衡任务。 - false：不启用。  - true：启用。                                                                                                                                                                                                                                                                                                 | false       |
   | dfs.balancer.auto.cron.expression      | HDFS均衡操作的CRON表达式，用于控制均衡操作的开始时间。 - 仅当"dfs.balancer.auto.enable"设置为"true"时生效。  - 默认值"0 1 \* \* 6"表示在每周六的1点执行任务。  - 参数取值的表达式介绍如[表2]所示。支持"\*"表示连续的时间段。            | 0 1 \* \* 6 |
   | dfs.balancer.auto.stop.cron.expression | HDFS停止均衡操作的CRON表达式，用于控制均衡操作的结束时间。 - 仅当"dfs.balancer.auto.enable"设置为"true"时生效。  - 参数取值的表达式介绍如[表2]所示。支持"\*"表示连续的时间段。  - 例如，参数值为"0 5 \* \* 6"，则表示在每周六的5点结束任务。   | -           |
      
    表2执行表达式参数解释 
   | 列   | 说明                 |
   |:---|:---|
   | 第1列 | 分钟，参数值为0～59。       |
   | 第2列 | 小时，参数值为0～23。       |
   | 第3列 | 日期，参数值为1～31。       |
   | 第4列 | 月份，参数值为1～12。       |
   | 第5列 | 星期，参数值为0～6，0表示星期日。 |
      
   
   
3. 修改自动Balancer的运行参数，如[表3]所示：
   
    表3自动Balancer运行参数 
   | 参数名                                 | 参数介绍                                                                                                                                                                           | 默认值  |
   |:---|:---|:---|
   | dfs.balancer.auto.threshold         | 表示磁盘容量百分比的均衡阈值。 仅当"dfs.balancer.auto.enable"设置为"true"时才有效。                                                               | 10   |
   | dfs.balancer.auto.exclude.datanodes | 不需要执行磁盘自动均衡的DataNode列表，用逗号分隔。 仅当"dfs.balancer.auto.enable"设置为"true"时才有效。                                                 | 默认为空 |
   | dfs.balancer.auto.bandwidthPerSec   | 每个DataNode可用于负载均衡的最大带宽量（单位：MB/s）。                                                                                                                                              | 20   |
   | dfs.balancer.auto.maxIdleIterations | Balancer的最大连续空闲迭代次数。一次空闲迭代为没有Block块被移动的迭代，当连续空闲迭代次数达到最大连续空闲迭代次数时，本次Balancer结束。当取值为-1时，代表无穷大。                                                                                   | 5    |
   | dfs.balancer.auto.maxDataNodesNum   | 该参数用来控制进行自动Balancer的DataNode数量。 假设该参数值为N，当N大于0， 则选择剩余空间比例最高的N个DataNode和最低的N个DataNode之间进行数据均衡；当N等于0， 则对集群中所有DataNode进行数据均衡。 | 5    |
      
   
   
4. 单击"保存"使配置生效。无需重启HDFS服务。 
   任务执行日志保存在主NameNode节点中，请查看"/var/log/Bigdata/hdfs/nn/hadoop-omm-balancer-*主机名*.log"。
   
   
 
#### 相关文档
- 如果执行start-balancer.sh，"hadoop-root-balancer-主机名.out"日志显示"Access denied for user test1. Superuser privilege is required"，请参见[执行balance常见问题定位方法](https://support.huaweicloud.com/trouble-mrs/mrs_03_0094.html)。
- 如果在HDFS客户端启动一个Balance进程，该进程被异常停止后，再次执行Balance操作时失败，请参见[HDFS执行Balance时被异常停止如何处理](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_1707.html#mrs_01_1707)。
- 如果数据出现不均衡，某磁盘过满而其他磁盘未写满，请参见[非HDFS数据残留导致数据分布不均衡](https://support.huaweicloud.com/trouble-mrs/mrs_03_0091.html)。
- 如果单个节点内DataNode的各磁盘使用率不均匀，请参见[节点内DataNode磁盘使用率不均衡](https://support.huaweicloud.com/trouble-mrs/mrs_03_0093.html)。
- 如果需要平衡正在运行的单个DataNode上的磁盘数据，请参见[配置HDFS DiskBalancer磁盘均衡](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_1678.html#mrs_01_1678)。
 
