Hadoop磁盘负载均衡

当你的hadoop集群,各个datanode磁盘空间用完后;或者是添加一个新的datanode时,你需要平衡各个磁盘的空间。

新加datanode/在结点上添加磁盘 -- 需要把旧的数据转移到新的datanode上面去;

配置参数的优化

一、预留一定空间

问题:

当各个datanodes中的磁盘(dfs.data.dir指定每个datanode使用的磁盘)写全满时,磁盘空间不足后,会导致mapreduce等其他任务无法写磁盘,报错

处理:

配置参数 dfs.datanode.du.reserved ,可以使每个磁盘保留相应的磁盘空间,单位使用bytes

二、平衡某一单独datanode

方法:

  • 关闭这个datanode

将高磁盘的节点强制Decommission

  • 扩展磁盘

后面具体细说如何扩展

  • 升降数据副本
hadoop fs -setrep
Usage: hadoop fs [generic options] -setrep [-R] [-w] <rep> <path> ...

# 具体降副本的命令如下:
hdfs dfs -setrep -R -w 2 hdfs://ns1/tmp/test.db 
# 升副本的命令如下:
hdfs dfs -setrep -R -w 3 hdfs://ns1/tmp/test.db 

1、-w:要求备份完成,这可能需要很长时间。

2、-R标识,是为了兼容,没有实际效果。

3、numReplicas:数字,表示备份的份数。

4、path:备份的内容地址。

改变一个文件在hdfs中的副本个数,数据会重写,而数据是先往磁盘使用率低的写; 这样可以达到磁盘高的数据往低的迁移。

  • distcp复制数据, 把数据清除
 % hadoop distcp hdfs://namenode1/foo hdfs://namenode2/bar

这条命令会把第一个集群(namenode为命令中指定的namenode1)中的/foo目录拷贝到第二个集群中的/bar目录下,于是在第二个集群中就得到了/bar/foo这样的目录结构,我们也可以指定多个拷贝源,但拷贝目的地只有一个。要注意的是,指定拷贝路径的时候要使用绝对路径。 

外文说明:https://wiki.apache.org/hadoop/FAQ#On_an_individual_data_node.2C_how_do_you_balance_the_blocks_on_the_disk.3F

追加一个磁盘到集群各机器

比如原来dfs.data.dir: /data1/hdfs/data/,/data2/hdfs/data/

现在添加多一块磁盘:/data3/hdfs/data/

一、步骤

1、停止集群, sbin/stop-all.sh

2、修改dfs.data.dir的配置 ,分发配置

3、启动集群(先只启动hdfs,./sbin/start-dfs.sh),该步的目的是:让DataNode去格式化/data3/hdfs/data/,填充其中的一些系统信息文件(例如:current ,current/VERSION,detach ,storage等)。

4、使用 http://namenodeAddress:50070/fsck 来检查文件系统(hdfs dfsadmin -report),并记录下结果,以便与修改后进行fsck比较,看文件系统是否健全 。

5、停止集群, sbin/stop-all.sh

6、进入/data{1-2}/hdfs/data/current 目录,将其中一些较大的子文件夹(如果是系统生成的名字一般是subdir**)mv到/data3/hdfs/data//current 下 。

7、启动集群 (先是hdfs,好做检查) 。

8、再次执行http://namenodeAddress:50070/fsck命令,将结果与前一次比较,没出问题的话,应该是一样的 。

二、移动current subdir*的原理

hdfs中文件的inode文件树信息以及每个文件对应的block信息存储在NN中的,每个block存储在那几台DN机器上是在集群启动时候,由每台datanode根据自身所拥有的block上报上去的。 datanode在启动时候,也是扫描自身dfs.data.dir的各个文件夹下的current(前提是这个目录的VERSION等必要信息文件时存在的,这个目录是合法的)目录,然后将下面存在block信息(有哪些block,存在那个文件夹下)上报到NN (详细参见DataNode的FSDataset代码)

三、一块磁盘损坏导致datanode停止的解决办法

dfs.datanode.failed.volumes.tolerated 参数从0修改为1

如有磁盘损坏,则该节点的datanode停止服务,改为1后,允许1块硬盘损坏不影响其他磁盘运行。重启后正常使用。

The number of volumes that are allowed to fail before a datanode stops offering service. By default any volume failure will cause a datanode to shutdown.

添加一个新datanode, 即添加一台机器

reblancer工具

添加新节点时,HDFS不会自动重新平衡。然而,HDFS提供了一个手动调用的重新平衡(reblancer)工具。

这个工具将整个集群中的数据块分布调整到一个可人工配置的百分比阈值。

如果在其他现有的节点上有空间存储问题,再平衡就会根据阀值,然后平衡分布数据。

-threshold : 指定了磁盘容量的余量百分比,用来判定一个节点的磁盘利用率是过低还是过高。(默认阈值为10%,每个datanode节点的实际hdfs存储使用量/集群hdfs存储量)

利用不足的数据节点 : 利用率 低于 平均利用率−threshold阈值

过度利用的数据节点:利用率 高于 平均利用率+threshold阈值

设置cmd:

./sbin/start-balancer.sh -threshold 5

具体解释例子如下: datanode hdfs使用量1000G; 集群总hdfs存储量10T即10000G; 则t值为1000/10000 = 0.1 = 10% 当执行balance的-t参数小于0.1时,集群进行balance; 命令为:

start-balancer.sh -threshold 10   

Expecting a number in the range of [1.0, 100.0]: 5%

sh $HADOOP_HOME/bin/start-balancer.sh –t 10%

这个命令中-t参数后面跟的是HDFS达到平衡状态的磁盘使用率偏差值。如果机器与机器之间磁盘使用率偏差小于10%,那么我们就认为HDFS集群已经达到了平衡的状态。

添加测试

如何测试添加datanode结点, 请看历史点击

按步骤添加datanode新机器后,执行balance

1、设置平衡时的带宽使用

可以设置为64M,即

hdfs dfsadmin -setBalancerBandwidth 67108864即可

2、默认balancer的threshold为10%,即各个节点与集群总的存储使用率相差不超过10%,我们可将其设置为5%

sbin/start-balancer.sh -threshold 5

等待集群自均衡完成即可