DataNode之间均衡
Apache
启动均衡
bin/start-balancer.sh –threshold 10
对于参数10,代表的是集群中各个节点的磁盘空间利用率相差不超过10%,可根据实际情况进行调整。
停止数据均衡
bin/stop-balancer.sh
CDH
说明
CDH在HDFS中提供了Balancer角色,使我们可以免于用命令行执行start-balancer.sh来手动配置。
Cloudera Manager里与Balancer有关的配置项有以下这些。
Balancing Threshold:Balancer平衡的阈值。平衡过程结束后,所有节点的磁盘占用率与集群的平均占用率之差必须小于threshold(按百分比计)。默认值是10。
Rebalancing Policy:计算平衡度的策略,有DataNode和BlockPool两种。前者是按节点级别来算,后者是按块池级别来算。后者只有对HDFS Federation才有效,所以我们选前者。
Included/Excluded Hosts:分别用来指定参与平衡的节点和被排除的节点。这样可以先人为判断数据分布情况,然后只让我们认为需要平衡的节点来操作。
dfs.balancer.moverThreads/dispatcherThreads:分别表示移动数据的线程池大小,和调度数据移动方案的线程池大小,默认值1000和200。
dfs.datanode.balance.max.concurrent.moves:表示能够同时移动的块(英文说法叫in-flight)数量,默认值50。
dfs.balancer.max-size-to-move:表示在Balancer的一次迭代(下面会提到)中,一个DataNode的最大数据交换量,默认值10G。
另外,还有一个出现在DataNode参数但又与平衡相关的:dfs.datanode.balance.bandwidthPerSec,即每个节点可以用来做平衡的最大带宽,默认1MB/s。这个值在多数情况下是偏小的,可以适当增大,如10甚至20。千万注意不能挤占太多带宽,以保证正常业务的运行。
操作
我们使用CDH5.12.1,如下

DataNode内磁盘均衡
hadoop2.x
背景
当HDFS的datanode节点挂载多个磁盘时,往往会出现两种数据不均衡的情况:
- 不同datanode节点间数据不均衡。
- 挂载数据盘的磁盘间数据不均衡。
特别是这种情况:当datanode原来是挂载单数据磁盘,当磁盘占用率很高之后,再挂载新的数据盘。由于hadoop 2.x 版本并不支持 HDFS 的磁盘间数据均衡,因此,会造成老数据磁盘占用率很高,新挂载的数据盘几乎很空。在这种情况下,挂载新的数据盘就失去了扩容HDFS数据盘的意义。
解决方法
虽然hadoop官方并没有在hadoop 2.X 提供标准的磁盘间数据均衡方法,但是我们也可以通过一些其它途径来达到磁盘间数据均衡。
总体方法:通过升降HDFS数据的副本数量,“一减一增”过程中,“一减”过程中会将老数据盘的数据块删除一个副本,“一增”过程中会将增加的一个副本数据均衡写入到老数据盘和新数据盘。通过“一减一增”,使得一部分老数据盘的数据转移到新的数据盘。
升降数据副本:比如默认HDFS的副本数是3份。
(1)使用命令将HDFS的副本数降为2,此时HDFS会删除老数据盘上面的1份副本;
(2)再使用命令将HDFS的副本数升为3,此时HDFS会将新增的1份副本均匀分布在所有的磁盘(新老数据盘机会 均等地分布这一份副本数据);
具体操作
- 检查HDFS健康程度。
hadoop fsck / - 做副本变更。
hadoop fs -setrep -R 2 / - 变更副本之后,做一次HDFS集群间的数据均衡。
./start-balancer.sh -threshold 5; - 将副本数量增为3,还原原来的副本数量。
hadoop fs -setrep -R 3 /
hadoop3.x
如果想要解决节点内多块磁盘数据不均衡的现象,就要借助DiskBalancer。在CDH 5.8.2+版本中,可以通过在CM中配置进行开启。如果使用的Hadoop版本是3.0+,就直接在hdfs-site.xml中加入相关项。
修改相关配置
<!-- 磁盘扩容策略 -->
<!-- 设置数据存储策略,默认为轮询,现在的情况显然应该用“选择空间多的磁盘存”模式 -->
<property>
<name>dfs.datanode.fsdataset.volume.choosing.policy</name>
<value>org.apache.hadoop.hdfs.server.datanode.fsdataset.AvailableSpaceVolumeChoosingPolicy</value>
</property>
<!-- 默认值0.75。它的含义是数据块存储到可用空间多的卷上的概率,由此可见,这个值如果取0.5以下,对该策略而言是毫无意义的,一般就采用默认值。-->
<property>
<name>dfs.datanode.available-space-volume-choosing-policy.balanced-space-preference-fraction</name>
<value>0.75f</value>
</property>
<!-- 配置各个磁盘的均衡阈值的,默认为10G(10737418240),在此节点的所有数据存储的目录中,找一个占用最大的,找一个占用最小的,如果在两者之差在10G的范围内,那么块分配的方式是轮询。 -->
<property>
<name>dfs.datanode.available-space-volume-choosing-policy.balanced-space-threshold</name>
<value>10737418240</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/data1,/data2,/data3,/data4</value>
</property>
执行均衡
hdfs diskbalancer -plan node2
hdfs diskbalancer -execute /system/diskbalancer/2016-Aug-17-17-03-56/172.26.10.16.plan.json
hdfs diskbalancer -query node2
看到PLAN_UNDER_PROGRESS 表示正在平衡,PLAN_DONE 表示完成。
线上案例
背景

方案一
如上面看到的,当有一块磁盘快满了以后,如果这个时候就是一块磁盘,那么可以先设置hdfs的副本,然后到2或者3副本以后,删除这块磁盘的数据。
方案二
- 复制DataNode数据到新的目录。
cp -af /dfs/dn/* /dfs_new/dn
- 配置hdfs-site.xml指向新复制过去的数据目录。
<property>
<name>dfs.datanode.data.dir</name>
<value>/dfs_new/dn</value>
</property>
- 重启DataNode或者执行块上报命令。
hdfs dfsadmin -triggerBlockReport datanode_host:ipc_port
如:hdfs dfsadmin -triggerBlockReport 192.168.31.35:50020。

评论区