关于HDFS Balancer的一些小技巧
- 前言
- 正文
- 原因分析
- Balancer工具做均衡
- 带宽设置
- 限定均衡范围
- 参数调优
- 结语
前言
使用HDFS的过程中,难免会出现数据不均衡的情况,直观表现就是有的服务器磁盘使用率高的吓人,有的服务器空闲的离谱;我在运维过程中也遇到很多这种情况,使用balancer工具做均衡也是总结了一些点,特意再次记录一下。
正文
原因分析
对于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内部各个磁盘进行数据均衡的工具,以后如果使用到再做记录。