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

  

  上面这个参数的意思:

  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 balancer is a tool that balances disk space usage alt="物联网" width="550" height="256" />

  考虑到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中是有设置的:

  

  dfs.datanode.balance.bandwidthPerSec

  10485760

  

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

  hdfs dfsadmin -fs hdfs://ns1:8020 -setBalancerBandwidth 104857600

  hdfs dfsadmin -fs hdfs://ns2:8020 -setBalancerBandwidth 104857600

  2、上下节点:

  其实将高磁盘的节点强制Decommission是最快最有效的方案。

  下节点的时候可能会出现有ns不能正常下掉的情况,其实这个时候节点的数据大部分已经移出去了,可能有一些块卡在那边没有移出去。

  这个时候只能一个一个节点将已经Decommissioned节点stop掉datanode进程,如果在namenode的页面上看到有丢失块的话,就需要将这个块先get到本地,在put上去。例如: