1. 背景
Hadoop的HDFS集群非常容易出现机器与机器之间磁盘利用率不平衡的情况,比如集群中添加新的数据节点。当HDFS出现不平衡状况的时候,将引发很多问题,比如MR程序无法很好地利用本地计算的优势,机器之间无法达到更好的网络带宽使用率,机器磁盘无法利用等等。可见,保证HDFS中的数据平衡是非常重要的。
在Hadoop中,包含一个Balancer程序,通过运行这个程序,可以使得HDFS集群达到一个平衡的状态。
2. HDFS balancer配置(可通过CM配置)
dfs.datanode.balance.max.concurrent.moves | 并行移动的block数量,默认5 |
dfs.datanode.balance.bandwidthPerSec | Balance工具所占用的带宽,默认1048576(1MB) |
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.blockpinning.enabled | 默认false |
3. 通过命令行使用balancer
hdfs balancer [-threshold <threshold>] [-policy <policy>] [-exclude [-f <hosts-file> | <comma-separated list of hosts>]] [-include [-f <hosts-file> | <comma-separated list of hosts>]] [-idleiterations <idleiterations>] |
参数说明:
-threshold | 某datanode的使用率和整个集群使用率的百分比差值阈值,达到这个阈值就启动hdfs balancer,取值从1到100,不宜太小,因为在平衡过程中也有数据写入,太小无法达到平衡 |
-policy | 分为blockpool和datanode,前者是block pool级别的平衡后者是datanode级别的平衡 |
-exclude | 不为空,则不在这些机器上进行平衡 |
-include | 不为空,则仅在这些机器上进行平衡 |
-idleiterations | 最大迭代次数 |
4. 集群平衡算法
4.1. 按使用情况分类
根据各datanode的使用情况,将集群中的节点分为:
4.2. 按使用情况配对
过度使用--过度闲置
过度使用--平均值下
平均值上--过度闲置
4.3. 找到待移动的block
源datanode的存储类型和目的datanode的存储类型一致
该block的副本未被安排
目的datanode不包含同样的副本
移动之后该机架上的block不会减少
4.4. 移动block
调用DataTransferProtocol .replaceBlock(..) 来移动,直到返回0,代表平衡完成