使用HDFS的过程中,难免会出现数据不均衡的情况,直观表现就是有的服务器磁盘使用率高的吓人,有的服务器空闲的离谱;我在运维过程中也遇到很多这种情况,使用balancer工具做均衡也是总结了一些点,特意再次记录一下。
对于HDFS来说,数据不均衡是个再正常不过的事情,就我所遇到的原因总结起来大概如下:
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-movename>
<value>107374182400value>
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内部各个磁盘进行数据均衡的工具,以后如果使用到再做记录。