HDFS Balancer

HDFS Balancer工具可以用来分析块的分布情况,并且可以重新分配DataNode中的数据。本文为您介绍如何使用HDFS Balancer工具,以及Balancer的主要调优参数。

背景信息

HDFS采用主从架构,其中NameNode管理文件系统的元数据(例如文件名、文件的块信息及其位置),而实际的数据块则存储在多个DataNode上。这种架构允许数据冗余存储,提高了系统的容错能力。

随着时间的推移,由于文件的添加、删除和修改操作,DataNodes之间的数据分布可能会变得不均衡,某些节点的存储空间可能接近饱和,而其他节点可能有大量的空闲空间。这种不均衡不仅影响了系统的存储效率,还可能增加数据丢失的风险,因为过度填充的节点更易受硬件故障的影响。

为了应对这一问题,HDFS提供了Balancer工具,这是一个命令行实用程序,旨在自动重新平衡DataNodes间的数据分布。Balancer通过移动数据块来减少各节点间的存储不均衡,确保整个集群的存储资源得到更有效的利用。

查看DataNode的容量和使用情况

查看DataNode的容量和使用情况,可以帮助您识别当前存储资源的分配状态,及时发现并解决存储空间不足的问题,确保数据在各个节点间均衡分布,从而提升系统整体的性能和稳定性。

  1. 登录待配置集群的主节点,详情请参见登录集群

  2. 执行以下命令,查看各DataNode的容量和使用情况。

hdfs dfsadmin -report

结果显示每个DataNode的总容量、使用量、使用率以及剩余空间的详细信息,有助于识别存储不均衡问题。

当发现数据分布极度不均,例如某些DataNode的存储使用率远高于其他节点,且差异超过默认或设定的平衡阈值(通常是10%),此时应启动HDFS Balancer。

启动HDFS Balancer

方式一:使用HDFS Balancer命令

HDFS Balancer命令语句如下。

hdfs balancer
[-threshold <threshold>]
[-policy <policy>]
[-exclude [-f <hosts-file> | <comma-separated list of hosts>]]
[-include [-f <hosts-file> | <comma-separated list of hosts>]]
[-source [-f <hosts-file> | <comma-separated list of hosts>]]
[-blockpools <comma-separated list of blockpool ids>]
[-idleiterations <idleiterations>]

Balancer主要参数如下表。

参数

描述

threshold

磁盘容量的百分数。

默认值为10%,表示上下浮动10%。

当集群总使用率较高时,需要调小Threshold,避免阈值过高。

当集群新增节点较多时,您可以适当增加Threshold,使数据从高使用率节点移向低使用率节点。

policy

平衡策略。支持以下策略:

  • datanode(默认):当每一个DataNode是平衡的时候,集群就是平衡的。

  • blockpool:当每一个DataNode中的blockpool是平衡的,集群就是平衡的。

exclude

Balancer排除特定的DataNode。

include

Balancer仅对特定的DataNode进行平衡操作。

source

仅选择特定的DataNode作为源节点。

blockpools

Balancer仅在指定的blockpools中运行。

idleiterations

最多允许的空闲循环次数。覆盖默认的5次。

方式二:使用start-balancer.sh工具

start-balancer.sh实际上是调用hdfs daemon start balancer命令。使用方式如下:

  1. 登录待配置集群的任意节点,详情请参见登录集群

  2. 可选:执行以下命令,修改Balancer的最大带宽。

    hdfs dfsadmin -setBalancerBandwidth <bandwidth in bytes per second>
    说明

    <bandwidth in bytes per second>为设置的最大带宽。例如,如果需要设置带宽控制为200 MB/s,对应值为200 * 1024 * 1024B,即209715200字节,则完整代码示例为hdfs dfsadmin -setBalancerBandwidth 209715200。为优化网络资源利用并保障核心业务流畅,在集群高负载情形下,建议适度削减数据平衡带宽,可以改为20971520(20 MB/s);在集群空闲时,为了加速数据均衡过程,建议将数据平衡带宽提高,可以改为1073741824(1 GB/s)。

  3. 执行以下命令,切换到hdfs用户并执行Balancer参数。

    • DataLake集群

      su hdfs
      /opt/apps/HDFS/hdfs-current/sbin/start-balancer.sh -threshold 5
    • Hadoop集群

      su hdfs
      /usr/lib/hadoop-current/sbin/start-balancer.sh -threshold 5
      说明

      -threshold 5:用于设置数据平衡的阈值。阈值被设定为5%,意味着当某个DataNode的数据存储量与集群平均存储量之差小于或等于5%时,平衡器认为该节点的数据分布是均衡的,不再尝试从该节点移出或移入数据块。不同的环境可能会根据实际情况调整这个阈值以达到理想的平衡效果。

  4. 执行以下命令,查看Balancer运行情况。

    • DataLake集群

      tail -f /var/log/emr/hadoop-hdfs/hadoop-hdfs-balancer-master-1-1.c-xxx.log
    • Hadoop集群

      tail -f /var/log/hadoop-hdfs/hadoop-hdfs-balancer-emr-header-1.cluster-xxx.log
      说明

      命令中的hadoop-hdfs-balancer-master-1-1.c-xxx.loghadoop-hdfs-balancer-emr-header-xx.cluster-xxx.log为上一步骤中获取到的日志名称。

    当提示信息包含Successfully字样时,表示执行成功。

Balancer调优参数

执行Balancer会占用一定的系统资源,建议在业务空闲期执行。默认情况下,不需要对HDFS Balancer参数进行额外调整。当需要对Balancer参数进行额外调整时,您可以在E-MapReduce控制台的HDFS服务页面,选择配置 > hdfs-site.xml,调整以下两类配置。

  • 客户端配置

    参数

    描述

    dfs.balancer.dispatcherThreads

    Balancer在移动Block之前,每次迭代时查询出一个Block列表,分发给Mover线程使用。

    说明

    dispatcherThreads是该分发线程的个数,默认为200。

    dfs.balancer.rpc.per.sec

    默认值为20,即每秒发送的RPC数量为20。

    因为分发线程调用大量getBlocks的RPC查询,所以为了避免NameNode由于分发线程压力过大,需要控制分发线程RPC的发送速度。

    例如,您可以在负载高的集群调整参数值,减小10或者5,对整体移动进度不会产生特别大的影响。

    dfs.balancer.getBlocks.size

    Balancer会在移动Block前,每次迭代时查询出一个Block列表,给Mover线程使用,默认Block列表中Block的大小为2 GB。因为getBlocks过程会对RPC进行加锁,所以您可以根据NameNode压力进行调整。

    dfs.balancer.moverThreads

    默认值为1000。

    Balancer处理移动Block的线程数,每个Block移动时会使用一个线程。

  • DataNode配置

    参数

    描述

    dfs.datanode.balance.bandwidthPerSec

    指定DataNode用于Balancer的带宽,通常推荐设置为100 MB/s,您也可以通过dfsadmin -setBalancerBandwidth 参数进行适当调整,无需重启DataNode。

    例如,在负载低时,增加Balancer的带宽。在负载高时,减少Balancer的带宽。

    dfs.datanode.balance.max.concurrent.moves

    默认值为5。

    指定DataNode节点并发移动的最大个数。通常考虑和磁盘数匹配,推荐在DataNode端设置为4 * 磁盘数作为上限,可以使用Balancer的值进行调节。

    例如:一个DataNode有28块盘,在Balancer端设置为28,DataNode端设置为28 * 4。具体使用时根据集群负载适当调整。在负载较低时,增加concurrent数;在负载较高时,减少concurrent数。

常见问题

Q:为什么Balancer的threshold设置为10(%),但是平衡以后看到差值为20%左右?

A:threshold的含义是控制每个DataNode的使用率不高于或者不低于集群平均的使用率,所以使用率最多和最少的DataNode在平衡后可能差值为20%。要减少这种差距,可以尝试把差值调节到5(%)。