Hadoop集群datanode磁盘不均衡的解决方案【转】

1、引言:html

Hadoop的HDFS集群很是容易出现机器与机器之间磁盘利用率不平衡的状况,好比集群中添加新的数据节点,节点与节点之间磁盘大小不同等等。当hdfs出现不平衡情况的时候,将引起不少问题,好比MR程序没法很好地利用本地计算的优点,机器之间没法达到更好的网络带宽使用率,机器磁盘没法利用等等。
2、问题:
因业务须要搭建一个新hadoop集群,并将老的hadoop集群中的数据迁移至新的hadoop集群,并且datanode节点不能所有上线,其中还可能会出现节点上线或下线的状况,这个时候就很容易出现机器与机器之间磁盘的均衡的状况,具体以下:
上图中能够看出max是94.18%,而min是0.37%,其中有600多台是达到94%的,这个时候在跑mapred的时候每每会报错误:
 
 
 
 
 
 
 
 
登录到该机器上查看服务器的磁盘,磁盘都快已经达到100%,以下:
由于咱们在hdfs-site.xml中设置了dfs.datanode.du.reserved的值,因此磁盘会有必定预留空间:
<property>
    <name>dfs.datanode.du.reserved</name>
    <value>107374182400</value>
</property>

上面这个参数的意思:java

  Reserved space in bytes per volume. Always leave this much space free for non dfs use.node

再查看datanode日志,但愿能找到可靠的线索:apache

这种错误没法经过namenode来避免,由于它不会再failed的时候去尝试往别的节点写数, 最初的办法是将该节点的datanode关闭掉,就能顺利地跑完这个mapreduce。服务器

再者查看namenode的页面,看到有好多datanode的节点的Remaining快要趋于0B了,这个时候就很容易出现上面的报错。网络

为了防止上面的报错再次出现以及避免hdfs数据不均衡,对hadoop集群作balance已经不可避免了!
2、解决方案
一、balancer
你们首先会想到hadoop自带的balancer,那就先介绍一下balancer!
Balancer.java中是这么描述balancer的:

The balancer is a tool that balances disk space usage on an HDFS cluster when some datanodes become full or when new empty nodes join the cluster.
The tool is deployed as an application program that can be run by the cluster administrator on a live HDFS cluster while applications adding and deleting files.app

下面的图片是官网中balancer命令得详解:tcp

考虑到balancer是最近须要常常作的操做,因此咱们本身开发了一个查看balancer状况的页面,结果以下:
上图能够看到每一个集群下balancer执行状况。
balance一天能成功移动的数据量大约在10-20T,这个数据量很难知足超大集群。
目前咱们调用balance会使用以下命令:
start-balancer.sh -threshold 20 -policy blockpool -include -f /tmp/ip.txt
上面的命令经过手工筛选出磁盘高的和磁盘低的放在ip.txt文件中,这样balance就只经过这文件里的了,另外还须要设置适当的threshold值,由于是多namespace的,因此须要选择blockpool模式。
另外带宽也是限制balance的一个因素,在hdfs-site.xml中是有设置的:
<property>
    <name>dfs.datanode.balance.bandwidthPerSec</name> 
    <value>10485760</value> 
</property>

可是这个须要重启,hadoop提供了一个动态调整的命令:oop

hdfs dfsadmin -fs hdfs://ns1:8020 -setBalancerBandwidth 104857600
hdfs dfsadmin -fs hdfs://ns2:8020 -setBalancerBandwidth 104857600
hdfs dfsadmin -fs hdfs://ns3:8020 -setBalancerBandwidth 104857600
hdfs dfsadmin -fs hdfs://ns4:8020 -setBalancerBandwidth 104857600
hdfs dfsadmin -fs hdfs://ns5:8020 -setBalancerBandwidth 104857600
 
 
二、上下节点:
其实将高磁盘的节点强制Decommission是最快最有效的方案。
下节点的时候可能会出现有ns不能正常下掉的状况,其实这个时候节点的数据大部分已经移出去了,可能有一些块卡在那边没有移出去。
这个时候只能一个一个节点将已经Decommissioned节点stop掉datanode进程,若是在namenode的页面上看到有丢失块的话,就须要将这个块先get到本地,在put上去。例如:
hdfs dfs -get hdfs://ns1/test/dt=2016-07-24/000816_0.lzo
 
hdfs dfs -put -f 000816_0.lzo hdfs://ns1/test/dt=2016-07-24/000816_0.lzo
 
hdfs dfs -chown dd_edw:dd_edw hdfs://ns1/test/dt=2016-07-24/000816_0.lzo  

前提条件须要将这个节点的datanode从新启动。ui

三、升降数据副本:
升降副本是一个无可奈何的办法,这样若是datanode有挂掉节点,就会增长丢失块的概率。
具体降副本的命令以下:
hdfs dfs -setrep -R -w 2 hdfs://ns1/tmp/test.db

升副本的命令以下:

hdfs dfs -setrep -R -w 3 hdfs://ns1/tmp/test.db

上面的命令是将ns1下的/tmp/test.db副本数降至2个,而后又将它升至3哥副本。具体的hdfs dfs -setrep命令以下图:

这样动态的升降副本能够解决。

另外在升降副本的遇到一个BUG:

推测多是namenode的replications模块有夯住状况,因此出现该状况执行kill掉进行,跳过该块再跑!

总结:之因此选择使用升降副本是由于它不受带宽的控制,另外在升降副本的时候hadoop是须要从新写数的,这个时候它会优先往磁盘低写数据,这样就能将磁盘高的数据迁移至磁盘低的。

四、distcp

DistCp (distributed copy) is a tool used for large inter/intra-cluster copying. It uses MapReduce to effect its distribution, error handling and recovery, and reporting. It expands a list of files and directories into input to map tasks, each of which will copy a partition of the files specified in the source list. Its MapReduce pedigree has endowed it with some quirks in both its semantics and execution. The purpose of this document is to offer guidance for common tasks and to elucidate its model.

在这里举一个例子:

经过distcp将/tmp/output12上的数据调用mapreduce迁移至/tmp/zhulh目录下,原先/tmp/output12上的数据仍是有存在的,可是它的块就发生了变化。

这个时候有人可能会说怎么不使用cp命令呢?

二者的区别以下:

CP的模式是不走mapreduce的;DISTCP的模式是走mapreduce的,因此它优先写有nodemanager的机器;

CP是单线程的,相似scp的模式,在执行速度上比DISTCP要慢不少。

想了解更加详细,请猛点这里

五、提升dfs.datanode.du.reserved值

官网是这么说的:Reserved space in bytes per volume. Always leave this much space free for non dfs use.

在上面的提到dfs.datanode.du.reserved的值是设成100G,由于namenode认为该节点还有剩余的空间,因此给分配到这里,假如这个块是128K,可是实际剩余空间只有100K,因此就会报上面的错误,假如把dfs.datanode.du.reserved成300G,让namenode知道该节点已经没有剩余空间,因此就不会往这里写数据了。

六、关闭nodemanger进程

在现有计算资源多余的状况下,能够考虑关闭高磁盘节点的nodemanager,避免在该节点起YarnChild,由于若是在该节点上进行计算的话,数据存储首先会往本地写一份,这样更加加剧了本地节点的负担。

七、删除旧数据

该方案是在无可奈何的状况下进行的,由于删掉的数据可能之后还得补回来,这样的话又是得要浪费必定的时间。

另外在删除数据时候就得须要跳过回收站才能算是真正删除,可使用的命令以下:

3、方案选择
考虑到有多达600台机器磁盘使用率达到94%,并且这部分高的机器是在同一个机房的,因此不能采用上下节点的方法,最好的办法以下:
一、提升dfs.datanode.du.reserved的值;
二、关闭nodemanager进程;
三、升降副本;
四、开启源码的balance;
人工的按期观察,当达到指望的效果的时候就是恢复成原样;在提升dfs.datanode.du.reserved的值就得须要考虑到datanode须要进行轮询的重启,这个时候就考虑到时间间隔,若是时间太短就可能就丢,若是过长就是费的时间比较多。
 这种方法比如:好比在节假日的时候,某个收费口的车辆特别多,那个时候执法人员就会封闭这个收费站的出口,等车辆过的差很少的时候再给开放。此次的方案有这个有点相似,当主机的dfs.datanode.du.reserved值高于目前磁盘使用的状况,namenode就不会分配数据过来了,经过升降副本和balance能快速的将本机的数据转移走。
4、结束语

本篇文章主要介绍了对hadoop数据出现不均衡状况下可使用的方案,并以实例来解决问题!

对此有兴趣的同窗欢迎一块儿交流 。

相关文章
相关标签/搜索