理想情况下,在一个集群汇总,我们希望每台机器都发挥自己最大的价值,磁盘的利用率均衡化。
往往因为网络,硬件,程序的原因,导致磁盘利用率出现严重的不均衡现象。
尤其是在DataNode节点出现故障或在现有的集群上新增、删除节点,或者某个节点机器内硬盘存储达到饱和值。会出现严重的磁盘利用率不均衡
当HDFS出现不平衡状况的时候,将引发很多问题
- MR程序无法很好地利用本地计算的优势
Map任务可能会分配到没有存储数据的机器,这将导致网络带宽的消耗,无法很好的进行本地计算 - 机器之间无法达到更好的网络带宽使用率
- 机器磁盘无法利用等等
当HDFS负载不均衡时,需要对HDFS进行数据的负载均衡调整,即对各节点机器上数据的存储分布进行调整。
从而让数据均匀的分布在各个DataNode上,均衡IO性能,防止热点的发生。
进行数据的负载均衡调整,必须要满足如下【原则】:
- 数据平衡不能导致数据块减少,数据块备份丢失,数据的备份数改变
- 管理员可以启动数据重分布程序或停止数据重分布程序
- 每次移动的数据量以及占用的网络资源,必须是可控的
数据重分布程序在执行的过程中,不能影响namenode的正常工作
数据均衡过程的核心是一个数据均衡算法,该数据均衡算法将不断迭代数据均衡逻辑,直至集群内数据均衡为止。
该数据均衡算法每次迭代的逻辑如下:
Hadoop数据重分布程序实现的逻辑流程如下所示:
- Rebalance程序作为一个独立的进程与namenode进行分开执行。
- 数据均衡服务(Rebalancing Server)首先要求 NameNode 生成 DataNode 数据分布分析报告
获取每个DataNode磁盘使用情况 - Rebalance Server汇总需要移动的数据分布情况,计算具体数据块迁移路线图。
即计算哪些机器需要将数据移动,哪些机器可以接受移动的数据,数据块迁移路线图,确保网络内最短路径 - 需要移动block的机器将数据移动的目的机器上去,同时删除自己机器上的block数据。
- Rebalance Server获取到本次数据移动的执行结果,并继续执行这个过程
一直到没有数据可以移动或者HDFS集群以及达到了平衡的标准为止。
HDFS 数据自动平衡脚本
start-balancer.sh脚本,通过运行这个工具,启动HDFS数据均衡服务。该工具可以做到热插拔,即无须重启计算机和 Hadoop 服务。
sh $HADOOP_HOME/bin/start-balancer.sh –t 10%
stop-balancer.sh
这个命令中-t参数后面跟的是HDFS达到平衡状态的磁盘使用率偏差值。
如果机器与机器之间磁盘使用率偏差小于10%,那么我们就认为HDFS集群已经达到了平衡的状态。
Balancer运行时允许占用的带宽默认设置为1M/S
现在我们设想这样一种情况:
- HDFS由2个rack组成。数据是3份备份。
- 2个rack中的机器磁盘配置不同,rack1中每一台机器的磁盘空间为1TB,rack2中每一台机器的磁盘空间为10TB。
- 现在大多数数据的2份备份都存储在第一个rack中。
在这样的一种情况下,HDFS级群中的数据肯定是不平衡的。运行Balancer程序。但运行结束以后,整个HDFS集群中的数据依旧不平衡:rack1中的磁盘剩余空间远远小于rack2。这是因为Balance程序的开发原则1导致的。
简单的说,就是在执行Balancer程序的时候,不会将数据中一个rack移动到另一个rack中,所以就导致了Balancer程序永远无法平衡HDFS集群的情况。
针对于这种情况,可以采取2种方案:
- 继续使用现有的Balancer程序,但是修改rack中的机器分布。将磁盘空间小的机器分叉到不同的rack中去。
- 修改Balancer程序,允许改变每一个rack中所具备的block数量,将磁盘空间告急的rack中存放的block数量减少
或者将其移动到其他磁盘空间富余的rack中去。