关于HDFS Balancer的一些小技巧

  • 前言
  • 正文
  • 原因分析
  • Balancer工具做均衡
  • 带宽设置
  • 限定均衡范围
  • 参数调优
  • 结语

前言

使用HDFS的过程中,难免会出现数据不均衡的情况,直观表现就是有的服务器磁盘使用率高的吓人,有的服务器空闲的离谱;我在运维过程中也遇到很多这种情况,使用balancer工具做均衡也是总结了一些点,特意再次记录一下。

hdfs 均衡进度命令 hdfs负载不均衡的原因_hdfs 均衡进度命令

正文

原因分析

对于HDFS来说,数据不均衡是个再正常不过的事情,就我所遇到的原因总结起来大概如下:

  • 组件部署导致:如NIFI等组件,同步数据至HDFS,若部署的节点同时也有DataNode,总会有块写在当前节点,很快节点就会使用率很高;
  • 磁盘更换导致:大数据量的集群会出现磁盘损坏的情况,无法修复时,就要更换磁盘,这个时候新上的磁盘就会是空的;
  • 数据的生命周期管理导致:数据不是一成不变的,进行生命周期管理是,删除数据对于集群分布的数据来说是随机的;
  • 配置导致:实际上这个是容易令人忽略的问题,使用Ambari等工具管理集群时,部署DN的时候会默认设置dfs.datanode.du.reserve,即预留的非HDFS可用的空间,比如10TB的磁盘,这个值被默认设置为1TB,这就会导致在评估DataNode可用空间的时候,只评估9TB,就会发现物理磁盘使用率不高,但是从WebUI看会很高;我一般来说都会手动设置为200-500GB;
  • 节点宕机维修导致:有时候,节点会发生宕机,如果短时间无法恢复,当节点再次上线,就会和其他节点出现不均衡的情,这个比较好理解。

Balancer工具做均衡

balancer工具的使用方式网速已经说烂了,这里我就写一下我使用Balancer工具过程中值得大家注意的地方,首先基本使用参数简单说下:

hdfs balancer
        [-policy <policy>]      平衡策略,可选datanode级别或者blockpool级别;
        [-threshold <threshold>]        平衡的百分比差值,假设HDFS整体使用率60%,该参数默认值10,则在每次迭代中,只有整体使用率在60%±10%的节点会参与到数据均衡中;
        [-exclude [-f <hosts-file> | <comma-separated list of hosts>]]  排除在均衡动作之外的DataNode节点,这部分节点不会进行均衡评估和操作;
        [-include [-f <hosts-file> | <comma-separated list of hosts>]]  包含在均衡动作之内的DataNode节点,只有这部分节点进行均衡评估和操作;
        [-source [-f <hosts-file> | <comma-separated list of hosts>]]   指定作为数据源的节点,在将高利用率的节点数据均衡到低使用率节点上时,这个参数很有用;
        [-blockpools <comma-separated list of blockpool ids>]   运行均衡操作的blockpool,若不是联邦集群,一般不会用到;
        [-idleiterations <idleiterations>]      本次均衡操作计划进行多少次迭代;
        [-runDuringUpgrade]    HDFS正在升级时,是否需要运行balancer,这个参数还没用到过

如果发现有的参数没有,那可能是因为hdfs的版本问题,不过大部分参数肯定都是有的。

带宽设置

balancer命令直接使用的话,一般只需要几个基础参数,但是默认的带宽速度是很低的,印象中只有10M,如果服务器性能好,可以适当调整,我一般就调到2G,动态调整方法如下:

hdfs dfsadmin -setBalancerBandwidth 2147483648

然后执行均衡命令:

hdfs balancer -policy datanode -threshold 10

限定均衡范围

集群比较大的时候,我们一般不会做全局的数据均衡,所以这个时候就要用include或者exclude进行节点的限制了,对于我来说include用的居多一些,首先创建一个节点清单文件include.txt,一行写一个IP或者主机名:

ttt101100.node
ttt101101.node
ttt101102.node
ttt101103.node

然后执行均衡命令:

hdfs balancer -policy datanode -threshold 10 -include -f include.txt

参数调优

迁移过程中注意运行日志会打印一些比较关键的信息:

22/01/20 09:28:41 INFO balancer.Balancer: dfs.balancer.movedWinWidth = 5400000 (default=5400000)
22/01/20 09:28:41 INFO balancer.Balancer: dfs.balancer.moverThreads = 1000 (default=1000)
22/01/20 09:28:41 INFO balancer.Balancer: dfs.balancer.dispatcherThreads = 200 (default=200)
22/01/20 09:28:41 INFO balancer.Balancer: dfs.datanode.balance.max.concurrent.moves = 50 (default=50)
22/01/20 09:28:41 INFO balancer.Balancer: dfs.balancer.getBlocks.size = 2147483648 (default=2147483648)
22/01/20 09:28:41 INFO balancer.Balancer: dfs.balancer.getBlocks.min-block-size = 10485760 (default=10485760)
22/01/20 09:28:41 INFO balancer.Balancer: dfs.balancer.max-size-to-move = 10737418240 (default=10737418240)
22/01/20 09:28:41 INFO balancer.Balancer: dfs.blocksize = 134217728 (default=134217728)

此处涉及了多个参数,解释几个比较重要的:

  • dfs.balancer.moverThreads:用于执行均衡的线程池大小,默认值是1000;
  • dfs.balancer.max-size-to-move:单次迭代中最大移动的数据量,默认是10GB,指单个source DataNode;
  • dfs.datanode.balance.max.concurrent.moves:并行移动的block数量,默认是50;

首先,我尝试单独设置max-size-to-move参数,在这之前先把默认参数下运行的日志保存:

记录时间							迭代				已均衡数据量			剩余待均衡数据量		本次迭代需要均衡的数据量
Jan 20, 2022 9:19:42 AM           0             10.04 GB            30.84 TB              10 GB
Jan 20, 2022 9:20:36 AM           1             20.08 GB            30.84 TB              10 GB

大概算一下速率在0.185GB/s
然后在启动balancer实例的节点的hdfs客户端文件中配置如下项:

<property>
  <name>dfs.balancer.max-size-to-move</name>
  <value>107374182400</value>
</property>

再次运行balancer命令并查看日志:

记录时间							迭代				已均衡数据量			剩余待均衡数据量		本次迭代需要均衡的数据量
Jan 20, 2022 9:43:40 AM           0            100.06 GB            30.80 TB             100 GB
Jan 20, 2022 9:48:51 AM           1            200.12 GB            30.77 TB             100 GB
Jan 20, 2022 9:53:14 AM           2            300.15 GB            30.75 TB             100 GB
Jan 20, 2022 9:58:08 AM           3            400.18 GB            30.72 TB             100 GB
Jan 20, 2022 10:02:40 AM          4            500.19 GB            30.69 TB             100 GB

大概算一下速率在0.311GB/s
配置实时生效了,单次迭代平衡的数据量从10GB增加到100GB,速率从0.185GB/s增加到0.311GB/s

而有关线程数的设置,必须重启HDFS才能生效,这是比较可惜的,根据社区的建议,dfs.datanode.balance.max.concurrent.moves参数可以尽可能设置大,因为在做平衡的时候,回取值balancer实例和DataNode之间的最小值,所以不用担心这个值太大造成磁盘IO的负担。

结语

除了集群各个节点间的数据同步以外,在Hadoop3.0+也提供了对于单个DataNode内部各个磁盘进行数据均衡的工具,以后如果使用到再做记录。