程序员人生 网站导航

HDFS节点内数据平衡:DiskBalancer

栏目:框架设计时间:2016-08-17 10:22:32

前言


做集群运维的同学可能都会遇到这样1个问题:Hadoop集群使用久了,各个节点上的数据会变得不均衡,多的到达70,80%,少的就10,20%.面对这类场景,我们的办法1般就是用HDFS自带的Balancer工具对其进行数据平衡.但有的时候,你会发现虽然节点间数据平衡了,但是节点内各个磁盘块的数据出现了不平衡的现象.这可是Balancer工具所干不了的事情.通过这个场景,我们引入本文的1个话题点:HDFS节点内数据平衡.这个问题很早的时候其实就被提出了,详见issue HDFS⑴312(Re-balance disks within a Datanode).我相信大家在使用Hadoop集群的时候或多或少都遇到过这个问题.本文就来好好聊聊这个话题,和社区目前对此的解决方案.

磁盘间数据不均衡状态的出现


磁盘间数据不均衡的现象源自于长时间写操作时数据大小不均衡.由于每次写操作你可以保证写磁盘的顺序性,但是你没法保证每次写入的数据量都是1个大小.比如A,B,C,D4块盘,你用默许的RoundRobin磁盘选择策略去写,最后4块盘都写过了,但是A,B可能写的block块就1M,而C,D可能就是128M.

磁盘间数据不均衡带来的问题


如果磁盘间数据不均衡现象确切出现了,它会给我们造成甚么影响呢?有人可能会想,它不就是1个普通磁盘嘛,又不是系统盘,系统盘使用空间太高是会影响系统性能,但是普通盘应当问题不大吧.这个观点听上去是没问题,但是只能说它斟酌的太浅了.我们从HDFS的读写层面来对这个现象做1个分析.这里归纳出了以下2点:

第1点,磁盘间数据不均衡间接引发了磁盘IO压力的不同.我们都知道,HDFS上的数据访问频率是很高的,这就会触及到大量读写磁盘的操作,数据多的盘自然的就会有更高频率的访问操作.如果1块盘的IO操作非常密集的话,必将会对它的读写性能造成影响.
第2点,高使用率磁盘致使节点可选存储目录减少.HDFS在写Block数据的时候,会挑选剩余可用空间满足待写Block的大小的情况下时,才会进行挑选,如果高使用率磁盘目录过量,会致使这样的候选块变少.所以这方面其实偏向的是对HDFS的影响.

磁盘间数据不均衡的传统解决方案


磁盘间数据不均衡现象出现了,目前我们有甚么办法解决呢?下面是2种现有解决方案:

方案1:节点下线再上线.将节点内数据不均衡的机器进行Decommision下线操作,下线以后再次上线.上线以后相当因而1个全新的节点了,数据也将会重新存储到各个盘上.这类做法给人感觉会比较暴力,当集群范围比较小的时候,代价太高,此时下线1个节点会对集群服务造成不小的影响.

方案2:人工移动部份数据block存储目录.此方案比方案1更加灵活1些,但是数据目录的移动要保证准确性,否则会造成移动完目录后数据找不到的现象.下面举1个实际的例子,比如我们想将磁盘1上的数据挪到磁盘2上.现有磁盘1的待移动存储目录以下:

/data/1/dfs/dn/ current/BP⑴788246909-xx.xx.xx.xx⑴412278461680/current/ finalized/subdir0/subdir1/

我移动到目标盘上的路径应当保持这样的路径格式不变,只变化磁盘所在的目录,目标路径以下:

/data/2/dfs/dn/current/BP⑴788246909-xx.xx.xx.xx⑴412278461680/current/finalized/subdir0/subdir1/

如果上述目录结构出现变化,就会造成HDFS找不到此数据块的情况.

社区解决方案:DiskBalancer


前面铺垫了这么多的内容,就是为了引出本节要重点论述的内容:DiskBalancer.DiskBalancer从名字上,我们可以看出,它是1个类似于Balancer的数据平衡工具.但是它的作用范围是被限制在了Disk上.首先这里要说明1点,DiskBalancer目前是未发布的功能特性,所以你们在现有发布版中是找不到此工具的.下面我将会全方面的介绍DiskBalancer,让大家认识,了解这个强大的工具.

DiskBalancer的设计核心


首先我们先来了解DiskBalancer的设计核心,这里与Balancer有1点点的区分.Balancer的核心点在于数据的平衡,数据平衡好就OK了.而DiskBalancer在设计的时候提出了2点目标:

第1.Data Spread Report.数据散布式的汇报.这是1个report汇报的功能.也就是说,DiskBalancer工具能支持各个节点汇报磁盘块使用情况的功能,通过这个功能我可以了解到目前集群内使用率TopN的节点磁盘.
第2.Disk Balancing.第2点才是磁盘数据的平衡.但是在磁盘内数据平衡的时候,要斟酌到各个磁盘storageType的不同,由于之条件到过HDFS的异构存储,不同盘可能存储介质会不同,目前DiskBalancer不支持跨存储介质的数据转移,所以目前都是要求在1个storageType下的.

以上2点取自于DiskBalancer的设计文档(DiskBalancer相干设计文档可见文章末尾的参考链接).

DiskBalancer的架构设计


此部份来讨论讨论DiskBalancer的架构设计.通过架构设计,我们能更好的了解它的1个整体情况.DiskBalancer的核心架构思想以下图所示:

这里写图片描述

上面进程经过了3个阶段,Discover(发现)到Plan(计划),再从Plan(计划)到Execute(履行).下面来详细解释这3个阶段:

Discover


发现阶段做的事情实际上就是通过计算各个节点内的磁盘使用情况,然后得出需要数据平衡的磁盘列表.这里会通过Volume Data Density磁盘使用密度的概念作为1个评判的标准,这个标准值将会以节点总使用率作为比较值.举个例子,如果1个节点,总使用率为75%,就是0.75,其中A盘使用率0.5(50%),那末A盘的volumeDataDensity密度值就等于0.75-0.5=0.25.同理,如果超越的话,则密度值将会为负数.因而我们可以用节点内各个盘的volumeDataDensity的绝对值来判断此节点内磁盘间数据的平衡情况,如果总的绝对值的和越大,说明数据越不平衡,这有点类似于方差的概念.Discover阶段将会用到以下的连接器对象:

1.DBNameNodeConnector
2.JsonConnector
3.NullConnector

其中第1个对象会调用到Balancer包下NameNodeConnector对象,以此来读取集群节点,磁盘数据情况

Plan


拿到上1阶段的汇报结果数据以后,将会进行履行计划的生成.Plan其实不是1个最小的履行单元,它的内部由各个Step组成.Step中会指定好源,目标磁盘.这里的磁盘对象是1层经过包装的对象:DiskBalancerVolume,其实不是原来的FsVolume.这里顺便提1下DiskBalancer中对磁盘节点等概念的转化:

  • 1.DiskBalancerCluster.通过此对象可以,读取到集群中的节点信息,这里的节点信息以DiskBalancerDataNode的方式所显现.
  • 2.DiskBalancerDataNode.此对象代表的是1个包装好后的DataNode.
  • 3.DiskBalancerVolume和DiskBalancerVolumeSet.DataNode磁盘对象和磁盘对象集合.DiskBalancerVolumeSet内的磁盘存储目录类型需要是同种StorageType.

Execute


最后1部份是履行阶段,所有的plan计划生成好了以后,就到了履行阶段.这些计划会被提交到各自的DataNode上,然后在DiskBalancer类中进行履行.DiskBalancer类中有专门的类对象来做磁盘间数据平衡的工作,这个类名称叫做DiskBalancerMover.在磁盘间数据平衡的进程中,高使用率的磁盘会移动数据块到相对低使用率的磁盘,等到满足1定阈值关系的情况下时,DiskBalancer会渐渐地退出.在DiskBalancer的履行阶段,有以下几点需要注意:

  • 1.带宽的限制.DiskBalancer中一样可以支持带宽的限制,默许是10M,通过配置项dfs.disk.balancer.max.disk.throughputInMBperSec进行控制.
  • 2.失败次数的限制.DiskBalancer中会存在失败次数的控制.在拷贝block数据块的时候,出现IOException异常,会进行失败次数的累加计数,如果超越最大容忍值,DiskBalancer也会退出.
  • 3.数据平衡阈值控制.DiskBalancer中可以提供1个磁盘间数据的平衡阈值,以此作为是不是需要继续平衡数据的标准,配置项为dfs.disk.balancer.block.tolerance.percent.

DiskBalancer的命令履行


DiskBalancer内部提供了许多种别的命令操作,比以下面的查询命令:

hdfs diskbalancer -query nodename.mycluster.com

我们也能够履行相应的plan命令来生成plan计划文件.

hdfs diskbalancer -uri hdfs://mycluster.com -plan node1.mycluster.com

然后我们可以用生成好后的json文件进行DiskBalancer的履行

hdfs diskbalancer -execute /system/diskbalancer/nodename.plan.json

固然,如果我们发现我们履行了毛病的plan,我们也能够通过cancel命令进行清除:

hdfs diskbalancer -cancel /system/diskbalancer/nodename.plan.json

hdfs diskbalancer -cancel <planID> -node <nodename>

在DiskBalancer中会触及到比较多的object-json的关系转换,所以你会看到1些带.json后缀的文件

小结


总而言之,DiskBalancer是1个很实用的功能特性.在Hadoop中,有专门的分支用于开发此功能,就是HDFS⑴312,感兴趣的同学可以下载Hadoop的最新代码进行学习.本人非常荣幸地也向此功能提交了1个小patch, issue编号,HDFS⑴0560.这个new feature很快就要在新版的Hadoop中发布了,相信会对Hadoop集群管理人员非常有帮助.

参考资料


1.https://issues.apache.org/jira/secure/attachment/12755226/disk-balancer-proposal.pdf
2.https://issues.apache.org/jira/secure/attachment/12810720/Architecture_and_test_update.pdf
2.https://issues.apache.org/jira/browse/HDFS⑴312
3.https://issues.apache.org/jira/browse/HDFS⑴0560

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐