AIOps 一场颠覆传统运维的盛筵
809
2023-03-15
Hadoop集群datanode磁盘不均衡的解决方案
一、引言:
Hadoop的HDFS集群非常容易出现机器与机器之间磁盘利用率不平衡的情况,比如集群中添加新的数据节点,节点与节点之间磁盘大小不一样等等。当hdfs出现不平衡状况的时候,将引发很多问题,比如MR程序无法很好地利用本地计算的优势,机器之间无法达到更好的网络带宽使用率,机器磁盘无法利用等等。
二、问题:
因业务需要搭建一个新hadoop集群,并将老的hadoop集群中的数据迁移至新的hadoop集群,而且datanode节点不能全部上线,其中还可能会出现节点上线或下线的情况,这个时候就很容易出现机器与机器之间磁盘的均衡的情况,具体如下:
上图中可以看出max是94.18%,而min是0.37%,其中有600多台是达到94%的,这个时候在跑mapred的时候往往会报错误:
登陆到该机器上查看服务器的磁盘,磁盘都快已经达到100%,如下:
因为我们在hdfs-site.xml中设置了dfs.datanode.du.reserved的值,所以磁盘会有一定预留空间:
dfs.datanode.du.reserved 107374182400
dfs.datanode.du.reserved 107374182400
上面这个参数的意思:
Reserved space in bytes per volume. Always leave this much space free for non dfs use.
再查看datanode日志,希望能找到可靠的线索:
这种错误无法通过namenode来避免,因为它不会再failed的时候去尝试往别的节点写数, 最初的办法是将该节点的datanode关闭掉,就能顺利地跑完这个mapreduce。
再者查看namenode的页面,看到有好多datanode的节点的Remaining快要趋于0B了,这个时候就很容易出现上面的报错。
为了防止上面的报错再次出现以及避免hdfs数据不均衡,对hadoop集群做balance已经不可避免了!
二、解决方案
1、balancer
大家首先会想到hadoop自带的balancer,那就先介绍一下balancer!
Balancer.java中是这么描述balancer的:
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.
下面的图片是官网中balancer命令得详解:
考虑到balancer是最近需要经常做的操作,所以我们自己开发了一个查看balancer情况的页面,结果如下:
上图可以看到每个集群下balancer执行情况。
balance一天能成功移动的数据量大约在10-20T,这个数据量很难满足超大集群。
目前我们调用balance会使用如下命令:
start-balancer.sh -threshold 20 -policy blockpool -include -f /tmp/ip.txt
start-balancer.sh -threshold 20 -policy blockpool -include -f /tmp/ip.txt
上面的命令通过手工筛选出磁盘高的和磁盘低的放在ip.txt文件中,这样balance就只通过这文件里的了,另外还需要设置适当的threshold值,因为是多namespace的,所以需要选择blockpool模式。另外带宽也是限制balance的一个因素,在hdfs-site.xml中是有设置的:
dfs.datanode.balance.bandwidthPerSec 10485760
dfs.datanode.balance.bandwidthPerSec 10485760
但是这个需要重启,hadoop提供了一个动态调整的命令:
hdfs dfsadmin -fs hdfs://ns1:8020 -setBalancerBandwidth 104857600 hdfs dfsadmin -fs hdfs://ns2:8020 -setBalancerBandwidth 104857600
hdfs dfsadmin -fs hdfs://ns1:8020 -setBalancerBandwidth 104857600 hdfs dfsadmin -fs hdfs://ns2:8020 -setBalancerBandwidth 104857600
hdfs dfs -get hdfs://ns1/test1/dt=2016-07-24/000816_0.lzo hdfs dfs -put -f 000816_0.lzo hdfs://ns1/test1/dt=2016-07-24/000816_0.lzo hdfs dfs -chown test1:test1 hdfs://ns1/test1/dt=2016-07-24/000816_0.lzo
hdfs dfs -get hdfs://ns1/test1/dt=2016-07-24/000816_0.lzo hdfs dfs -put -f 000816_0.lzo hdfs://ns1/test1/dt=2016-07-24/000816_0.lzo hdfs dfs -chown test1:test1 hdfs://ns1/test1/dt=2016-07-24/000816_0.lzo
前提条件需要将这个节点的datanode重新启动。3、升降数据副本:升降副本是一个迫不得已的办法,这样如果datanode有挂掉节点,就会增加丢失块的几率。具体降副本的命令如下:
hdfs dfs -setrep -R -w 2 hdfs://ns1/tmp/test.db
hdfs dfs -setrep -R -w 2 hdfs://ns1/tmp/test.db
升副本的命令如下:
hdfs dfs -setrep -R -w 3 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是需要重新写数的,这个时候它会优先往磁盘低写数据,这样就能将磁盘高的数据迁移至磁盘低的。
4、distcp
在这里举一个例子:
通过distcp将/tmp/output12上的数据调用mapreduce迁移至/tmp/zhulh目录下,原先/tmp/output12上的数据还是有存在的,但是它的块就发生了变化。
这个时候有人可能会说怎么不使用cp命令呢?
两者的区别如下:
CP的模式是不走mapreduce的;DISTCP的模式是走mapreduce的,所以它优先写有nodemanager的机器;
CP是单线程的,类似scp的模式,在执行速度上比DISTCP要慢很多。
5、提高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知道该节点已经没有剩余空间,所以就不会往这里写数据了。
6、关闭nodemanger进程
在现有计算资源多余的情况下,可以考虑关闭高磁盘节点的nodemanager,避免在该节点起YarnChild,因为如果在该节点上进行计算的话,数据存储首先会往本地写一份,这样更加加重了本地节点的负担。
7、删除旧数据
该方案是在迫不得已的情况下进行的,因为删掉的数据可能以后还得补回来,这样的话又是得要浪费一定的时间。
另外在删除数据时候就得需要跳过回收站才能算是真正删除,可以使用的命令如下:
三、方案选择
考虑到有多达600台机器磁盘使用率达到94%,而且这部分高的机器是在同一个机房的,所以不能采用上下节点的方法,最好的办法如下:
1、提高dfs.datanode.du.reserved的值;
2、关闭nodemanager进程;
3、升降副本;
4、启动hadoop自带的balance;
人工的定期观察,当达到期望的效果的时候就是恢复成原样;在提高dfs.datanode.du.reserved的值就得需要考虑到datanode需要进行轮询的重启,这个时候就考虑到时间间隔,如果时间过短就可能就丢,如果过长就是费的时间比较多。
这种方法好比:比如在节假日的时候,某个收费口的车辆特别多,那个时候执法人员就会封闭这个收费站的出口,等车辆过的差不多的时候再给开放。这次的方案有这个有点类似,当主机的dfs.datanode.du.reserved值高于目前磁盘使用的情况,namenode就不会分配数据过来了,通过升降副本和balance能快速的将本机的数据转移走。
四、结束语
本篇文章主要介绍了对hadoop数据出现不均衡情况下可以使用的方法,及我们情况下使用的方案!
发表评论
暂时没有评论,来抢沙发吧~