HDFS数据平衡

一、datanode之间的数据平衡

1.1、介绍

​ Hadoop 分布式文件系统(Hadoop Distributed FilSystem),简称 HDFS,被设计成适合运行在通用硬件上的分布式文件系统。它和现有的分布式文件系统有很多的共同点。HDFS 是一个高容错性的文件系统,提供高吞吐量的数据访问,非常适合大规模数据集上的应用。HDFS 是 Apache Hadoop Core 项目一部分。
​ Hadoop的HDFS集群非常容易出现机器与机器之间磁盘利用率不平衡的情况,比如集群中添加新的数据节点。当HDFS出现不平衡状况的时候,将引发很多问题,比如MR程序无法很好地利用本地计算的优势,机器之间无法达到更好的网络带宽使用率,机器磁盘无法利用等等。可见,保证HDFS中的数据平衡是非常重要的

1.2、原则

  1. 在执行数据重分布的过程中,必须保证数据不能出现丢失,不能改变数据的备份数,不能改变每一个rack中所具备的block数量。
  2. 系统管理员可以通过一条命令启动数据重分布程序或者停止数据重分布程序。
  3. Block在移动的过程中,不能暂用过多的资源,如网络带宽。
  4. 数据重分布程序在执行的过程中,不能影响name node的正常工作。

1.3、流程

  1. Rebalance程序作为一个独立的进程与name node进行分开执行。
  2. Rebalance Server从Name Node中获取所有的Data Node情况:每一个Data Node磁盘使用情况。
  3. Rebalance Server计算哪些机器需要将数据移动,哪些机器可以接受移动的数据。并且从Name Node中获取需要移动的数据分布情况。
  4. Rebalance Server计算出来可以将哪一台机器的block移动到另一台机器中去。
  5. 需要移动block的机器将数据移动的目的机器上去,同时删除自己机器上的block数据。
  6. Rebalance Server获取到本次数据移动的执行结果,并继续执行这个过程,一直没有数据可以移动或者HDFS集群以及达到了平衡的标准为止

步骤1:Rebalance Server从NameNode中获取所有的DataNode情况:每一个DataNode磁盘使用情况。
步骤2:Rebalance Server计算哪些机器需要将数据移动,哪些机器可以接受移动的数据。并且从NameNode中获取需要移动的数据分布情况。
步骤3:Rebalance Server计算出来可以将哪一台机器的block移动到另一台机器中去。
步骤4,5,6:需要移动block的机器将数据移动的目的机器上去,同时删除自己机器上的block数据。
步骤7:Rebalance Server获取到本次数据移动的执行结果,并继续执行这个过程,一直没有数据可以移动或者HDFS集群以及达到了平衡的标准为止

Balancer退出条件:

  • * The cluster is balanced;
    * No block can be moved;
    * No block has been moved for specified consecutive iterations (5 by default);
    * An IOException occurs while communicating with the namenode;
    * Another balancer is running
      脚本自动退出条件
      集群内数据已经达到平衡条件了。
      没有数据块可以被移动。
      连续三次迭代中都没有数据块移动。
      NameNode 交互失败;
      另外已经有数据平衡进程启动
    

    1.4、使用命令

    hdfs balancer -help
    Usage: java Balancer
        [-policy <policy>]    the balancing policy: datanode or blockpool
        [-threshold <threshold>]    Percentage of disk capacity
        [-exclude [-f <hosts-file> | comma-sperated list of hosts]]    Excludes the specified datanodes.
        [-include [-f <hosts-file> | comma-sperated list of hosts]]    Includes only the specified datanodes.
    

    -threshold:某datanode的使用率和整个集群使用率的百分比差值阈值,达到这个阈值就启动hdfs balancer,取值从1到100,不宜太小,因为在平衡过程中也有数据写入,太小无法达到平衡
    -policy:分为blockpool和datanode,前者是block pool级别的平衡后者是datanode级别的平衡,BlockPool 策略平衡了块池级别和 DataNode 级别的存储。BlockPool 策略仅适用于 Federated HDFS 服务
    -exclude:不为空,则不在这些机器上进行平衡
    -include:不为空,则仅在这些机器上进行平衡
    -idleiterations:最大迭代次数

1.5、参数调整

dfs.datanode.balance.bandwidthPerSec = 31457280 ,指定DataNode用于balancer的带宽为30MB,这个示情况而定,如果交换机性能好点的,完全可以设定为50MB,单位是Byte,如果机器的网卡和交换机的带宽有限,可以适当降低该速度,默认是1048576(1MB),hdfs dfsadmin-setBalancerBandwidth 52428800可以通过命令设置
-threshold:默认设置为10,参数取值范围0-100,参数含义:判断集群是否平衡的目标参数,每一个 datanode 存储使用率和集群总存储使用率的差值都应该小于这个阀值 ,理论上,该参数设置的越小,整个集群就越平衡,但是在线上环境中,hadoop集群在进行balance时,还在并发的进行数据的写入和删除,所以有可能无法到达设定的平衡参数值
dfs.datanode.balance.max.concurrent.moves = 50,指定DataNode上同时用于balance待移动block的最大线程个数
dfs.balancer.moverThreads:用于执行block移动的线程池大小,默认1000
dfs.balancer.max-size-to-move:每次balance进行迭代的过程最大移动数据量,默认10737418240(10GB)
dfs.balancer.getBlocks.size:获取block的数量,默认2147483648(2GB)
dfs.balancer.getBlocks.minblock-size:用来平衡的最小block大小,默认10485760(10MB)
dfs.datanode.max.transfer.threads:建议为16384),指定用于在DataNode间传输block数据的最大线程数
dfs.namenode.replication.max-streams:

带宽即为平衡过程中的带宽速率 参数为dfs.datanode.balance.bandwidthPerSec 一般默认10M/s

命令:hdfs dfsadmin -setBalancerBandwidth   newbandwidth
其中newbandwidth是每个DataNode在平衡操作期间可以使用的最大网络带宽量,以每秒字节数为单位
比如:hdfs dfsadmin -setBalancerBandwidth 104857600
hdfs balancer -Ddfs.balancer.block-move.timeout=600000 //默认相差值为10% 带宽速率为10M/s
过程信息会直接打印在客户端 ctrl+c即可中止

#可以手动设置相差值 一般相差值越小 需要平衡的时间就越长
hdfs balancer -threshold 20  //设置为20% 这个参数本身就是百分比 不用带%
#如果怕影响业务可以动态设置一下带宽再执行上述命令
hdfs dfsadmin -setBalancerBandwidth 1048576 // 1M/s

#或者直接带参运行
hdfs balancer -Ddfs.datanode.balance.bandwidthPerSec=1048576 -Ddfs.balancer.block-move.timeout=600000
//带宽为1M/s

1.6、注意事项

  1. 默认的DataNode策略是在DataNode级别均衡存储,但均衡器不会在DataNode的各个存储卷之间均衡数据。
  2. 仅当DataNode使用的DFS百分比和(由集群使用的)平均DFS之间的差大于(或小于)规定阈值时,均衡器才会均衡DataNode。否则,它不会重新均衡集群。
  3. 均衡器运行多长时间取决于集群的大小和数据的不平衡程度。第一次运行均衡器,或者不经常调度均衡器,以及在添加一组DataNode之后运行均衡器,它将运行很长时间(通常是几天,如果数据量达到PB或者接近EB级别,可能需要一个多月的时间来均衡哟~)
  4. 如果有一个数据写入和删除频繁的集群,集群可能永远不会达到完全均衡的状态,均衡器仅仅将数据从一个节点移动到另一个节点。
  5. 向集群添加新节点后最好立即运行均衡器。如果一次添加大量节点,则运行均衡器需要一段时间才能完成其工作。
  6. 如果确定阈值?这很容易,秩序选择整个集群中节点最低DFS使用百分比即可。不必花费大量的时间了解每个节点使用的DFS百分比,使用”hdfs dfsadmin -report”命令即可找出正确的阈值。阈值越小,均衡器需要执行的工作越多,集群就越均衡。

二、节点磁盘之间的数据平衡

2.1、背景

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

当写入新block时,DataNodes将根据选择策略(循环策略可用空间策略)来选择block的磁盘(卷)。

  • 循环策略:它将新block均匀分布在可用磁盘上。默认此策略。

  • 可用空间策略:此策略将数据写入具有更多可用空间(按百分比)的磁盘。

但是,在长期运行的群集中采用循环策略时,DataNode有时会不均匀地填充其存储目录(磁盘/卷),从而导致某些磁盘已满而其他磁盘却很少使用的情况。发生这种情况的原因可能是由于大量的写入和删除操作,也可能是由于更换了磁盘。

另外,如果我们使用基于可用空间的选择策略,则每个新写入将进入新添加的空磁盘,从而使该期间的其他磁盘处于空闲状态。这将在新磁盘上创建瓶颈。

因此,需要一种Intra DataNode Balancing(DataNode内数据块的均匀分布)来解决Intra-DataNode偏斜(磁盘上块的不均匀分布),这种偏斜是由于磁盘更换或随机写入和删除而发生的。

2.2、介绍

HDFS disk balancer是Hadoop 3中引入的命令行工具,用于平衡DataNode中的数据在磁盘之间分布不均匀问题。 这里要特别注意,HDFS disk balancer与HDFS Balancer是不同的:

  • HDFS disk balancer针对给定的DataNode进行操作,并将块从一个磁盘移动到另一个磁盘,是DataNode内部数据在不同磁盘间平衡;

  • HDFS Balancer平衡了DataNode节点之间的分布。

2.3、设计目标

HDFS Disk balancer支持两个主要功能,即报告平衡

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

2.3.1数据传播报告

​ 为了定义一种方法来衡量集群中哪些计算机遭受数据分布不均的影响,HDFS磁盘平衡器定义了HDFS Volume Data Density metric(卷/磁盘数据密度度量标准)和Node Data Density metric(节点数据密度度量标准)。

  • HDFS卷数据密度度量标准能够比较数据在给定节点的不同卷上的分布情况。

  • 节点数据密度度量允许在节点之间进行比较。

Volume data density metric计算过程

假设有一台具有四个卷/磁盘的计算机-Disk1,Disk2,Disk3,Disk4,各个磁盘使用情况:

Disk1 Disk2 Disk3 Disk4
capacity 200 GB 300 GB 350 GB 500 GB
dfsUsed 100 GB 76 GB 300 GB 475 GB
dfsUsedRatio 0.5 0.25 0.85 0.95
volumeDataDensity 0.20 0.45 -0.15 -0.24

Total capacity= 200 + 300 + 350 + 500 = 1350 GB

Total Used= 100 + 76 + 300 + 475 = 951 GB

因此,每个卷/磁盘上的理想存储为:

Ideal storage = total Used ÷ total capacity= 951÷1350 = 0.70

也就是每个磁盘应该保持在 70%理想存储容量。

VolumeDataDensity = idealStorage – dfs Used Ratio

比如Disk1的卷数据密度= 0.70-0.50 = 0.20。其他Disk以此类推。

volumeDataDensity的正值表示磁盘未充分利用,而负值表示磁盘相对于当前理想存储目标的利用率过高。

Node Data Density计算过程

Node Data Density(节点数据密度)= 该节点上所有卷/磁盘volume data density绝对值的总和。

上述例子中的节点数据密度=|0.20|+|0.45|+|-0.15|+|-0.24| =1.04

较低的node Data Density值表示该机器节点具有较好的扩展性,而较高的值表示节点具有更倾斜的数据分布。

一旦有了volumeDataDensity和nodeDataDensity,就可以找到集群中数据分布倾斜的节点,或者可以获取给定节点的volumeDataDensity。

一旦有了volumeDataDensity和nodeDataDensity,就可以找到集群中数据分布倾斜的节点,或者可以获取给定节点的volumeDataDensity。

2.4、架构

DiskBalancer的架构设计.DiskBalancer的核心架构思想分为三个部分

2.4.1、Discover

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

DBNameNodeConnector
sonConnector
NullConnector

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

2.4.2、Plan

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

  1. DiskBalancerCluster:通过此对象可以,读取到集群中的节点信息,这里的节点信息以DiskBalancerDataNode的方式所呈现。

  2. DiskBalancerDataNode.此对象代表的是一个包装好后的DataNode.

  3. DiskBalancerVolume和DiskBalancerVolumeSet.DataNode磁盘对象以及磁盘对象集合.DiskBalancerVolumeSet内的磁盘存储目录类型需要是同种StorageType.

2.4.3、Execute

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

  1. 带宽的限制.DiskBalancer中同样可以支持带宽的限制,默认是10M,通过配置项dfs.disk.balancer.max.disk.throughputInMBperSec进行控制.

  2. 失败次数的限制.DiskBalancer中会存在失败次数的控制.在拷贝block数据块的时候,出现IOException异常,会进行失败次数的累加计数,如果超出最大容忍值,DiskBalancer也会退出.

  3. 数据平衡阈值控制.DiskBalancer中可以提供一个磁盘间数据的平衡阈值,以此作为是否需要继续平衡数据的标准,配置项为dfs.disk.balancer.block.tolerance.percent.

2.5、相关命令

2.5.1、plan命令

默认情况下,Hadoop群集上已经启用了Disk Balancer功能。通过在hdfs-site.xml中调整dfs.disk.balancer.enabled参数值为true,选择在Hadoop中是否启用磁盘平衡器。

命令:hdfs diskbalancer -plan

-out	//控制计划文件的输出位置
-bandwidth	//设置用于运行Disk Balancer的最大带宽。默认带宽10 MB/s。
–thresholdPercentage  //定义磁盘开始参与数据重新分配或平衡操作的值。默认的thresholdPercentage值为10%,这意味着仅当磁盘包含的数据比理想存储值多10%或更少时,磁盘才用于平衡操作。
-maxerror	//它允许用户在中止移动步骤之前为两个磁盘之间的移动操作指定要忽略的错误数。
-v	//详细模式,指定此选项将强制plan命令在stdout上显示计划的摘要。
-fs	//此选项指定要使用的NameNode。如果未指定,则Disk Balancer将使用配置中的默认NameNode。

2.5.2、Excute命令

命令:hdfs diskbalancer -execute

execute命令针对为其生成计划的DataNode执行计划。

2.5.3、查询命令

命令:hdfs diskbalancer -query

query命令从运行计划的DataNode获取HDFS磁盘平衡器的当前状态。

2.5.4、取消命令

命令:hdfs diskbalancer -cancel

hdfs diskbalancer -cancel planID node

cancel命令取消运行计划。

2.5.5、汇报命令

命令:hdfs diskbalancer -fs https://namenode.uri -report <file://>

三、参考地址

https://blog.csdn.net/nothair/article/details/114271275

https://www.cnblogs.com/yinzhengjie2020/p/13342039.html

https://blog.51cto.com/u_12445535/2354958 #balancer命令

https://www.jianshu.com/p/f7c1cd476601 #源码分析

https://www.cnblogs.com/hit-zb/p/11939161.html #同上

https://zhuanlan.zhihu.com/p/340472799 #hdfs命令

https://cloud.tencent.com/developer/article/1557887 #原理

https://zhuanlan.zhihu.com/p/303044375 #均衡命令

https://zhuanlan.zhihu.com/p/333842462 #hdfs存策略

张贴在2