做集群运维的同学可能都会遇到这样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从名字上,我们可以看出,它是1个类似于Balancer的数据平衡工具.但是它的作用范围是被限制在了Disk上.首先这里要说明1点,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的架构设计.通过架构设计,我们能更好的了解它的1个整体情况.DiskBalancer的核心架构思想以下图所示:
上面进程经过了3个阶段,Discover(发现)到Plan(计划),再从Plan(计划)到Execute(履行).下面来详细解释这3个阶段:
发现阶段做的事情实际上就是通过计算各个节点内的磁盘使用情况,然后得出需要数据平衡的磁盘列表.这里会通过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对象,以此来读取集群节点,磁盘数据情况
拿到上1阶段的汇报结果数据以后,将会进行履行计划的生成.Plan其实不是1个最小的履行单元,它的内部由各个Step组成.Step中会指定好源,目标磁盘.这里的磁盘对象是1层经过包装的对象:DiskBalancerVolume,其实不是原来的FsVolume.这里顺便提1下DiskBalancer中对磁盘节点等概念的转化:
最后1部份是履行阶段,所有的plan计划生成好了以后,就到了履行阶段.这些计划会被提交到各自的DataNode上,然后在DiskBalancer类中进行履行.DiskBalancer类中有专门的类对象来做磁盘间数据平衡的工作,这个类名称叫做DiskBalancerMover.在磁盘间数据平衡的进程中,高使用率的磁盘会移动数据块到相对低使用率的磁盘,等到满足1定阈值关系的情况下时,DiskBalancer会渐渐地退出.在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
上一篇 扑克牌顺子
下一篇 Java对象的序列化和反序列化