HBase学习之负载均衡(balance)

有关负载均衡的相关源码分析请参考上一篇博文:
http://blog.csdn.net/u013080251/article/details/68947654

负载均衡是计算机网络领域的一个专业术语,该术语在分布式系统领域应用非常广泛。对于HBase来讲,不同节点(RegionServer)用户请求需要负载均衡技术,其实在HBase很早的版本中已经实现了负载均衡,0.92版本后HBase的负载均衡算法可以通过实现LoadBalancer接口的hbase.master.loadbalancer.class来自定义。HBase通过Region数量实现简单的负载均衡,虽然这种方式比较简单,但官方认为这样的实现是最简洁、高效的,能够满足绝大部分的需求。接下来将介绍三种负载均衡计划的原理和应用场景,以及手动控制的负载均衡。


一、全局计划
全局计划是最常见的负载均衡,它贯穿在整个集群的平衡运行期内,负载均衡以特定时间间隔(hbase.balancer.period默认是5分钟)执行。但是,当遇到如下场景时不进行全局负载均衡:

  • 均衡负载开关balanceSwitch关闭。
  • HMaster未完成初始化操作。
  • RIT中有未处理完的Region(当前有region处于splitting状态)。
  • 有正在处理的Dead RegionServer。
  • RegionServer上的平均Region数量小于等于1.

1.算法流程
1)两个有效参数:MIN = floor(average)(表示下限)和MAX=ceil(average)(表示上限)。
2)循环过载机器,将Region卸载到MAX数量,在小于等于MAX时停止排序Region(按时间新旧)。
3)遍历最轻负载机器,分配Region直到Server达到MIN值。在大于等于MIN时停止。这些Region都是之前卸载的。可能没有足够地卸载Region让轻负载的机器达到MIN值,如果这样,在Region数等于neededRegions(轻负载机器的数量)时停止。可能我们分配了卸载的Region到轻负载机器,但是仍然有Region没有分配出去,这种情况下,本步骤完成,在下面步骤中再做处理。
4)如果neededRegions是非零的值,遍历负载最重的机器,从每台机器上卸载一个Region,使得它们的值从MAX到MIN。
5)现在有很多Region等待分配,遍历最轻的负载机器(多台),分配Region到MIN。
6)如果仍然有Region没有分配,遍历最轻的负载机器(多台),这次分配Region到MAX。
7)所有Server的Region数量时MAX或者MIN,另外,所有大于等于MAX的Server保证在均衡完成后都是MAX个Region。从而保证Region移动的最小数量。
其中,轻负载指的是Region数量小于等于AVG,过载指大于等于AVG,所有的RegionServer都按照负载从大到小排序,存放在TreeMap中(保证先遍历过载Server)。

2.算法举例分析
下面通过一个特定的场景进行算法分析,假定整个集群中总共存在3台RegionServer,每台RegionServer的负载如下图10-6所示。

这里写图片描述

1)现在需要进行负载均衡,这时HMaster已经拥有了所有RegionServer的负载情况,首先计算整个集群中所有负载的Region总量numRegions,并把这些Region按照负载的情况进行排序,排序后负载如图10-7所示。

numRegions = 50

这里写图片描述

2)计算每个RegionServer需要承载的Region的平均值:

Average = numRegions / numServers = 16.7

计算是否需要进行负载均衡的阈值,slop默认的值是0(0.96版本里是0.2),这相当于对average做ceil和floor运算:

floor = Math.floor(average * (1 - slop))
ceiling = Math.ceil(average * (1 + slop))

判定如果集群中负载的最小值大于floor,并且最大值小于ceil,这时直接返回不需要进行负载均衡。
3)计算每个RegionServer需要承载的Region的最大值和最小值,其实也就相当于对average取ceil和floor操作:

min = numRegions / numServers = 16
max = numRegions % numServers == 0 ? min:min+1 = 17

4)从负载最大的RegionServer开始遍历(此时是RegionServer3),如果找到一个RegionServer的负载小于等于上面计算的max(17)停止,如果当前的rs的负载量比max大,这时变量serverOverload++,随机打乱该rs上的Region(类似于洗牌shuffle算法),计算需要从该RegionServer上转移的Region的数量。

numToOffload = Math.min(regionCount - max, regions.size())

然后从该RegionServer中的Region中转移numToOffload个Region(并没有完全实际转移,这里仅仅生成了转移的计划,使用类RegionPlan表示,并且只设置了转移的源地址,目标的地址这时并未设置。)此时的集群负载情况如图10-8所示。

这里写图片描述

regionsToMove变量保存了RegionServer3中12个Region的信息,设置源地址是RegionServer3,但是目的地址暂时未知。
5)从负载最小的RegionServer开始遍历(此时是RegionServer2),如果找到一个负载比上面计算的min大的RegionServer则停止;如果当前的RegionServer的负载量比min小,这时就可以为第4步中没有设置目的地址RegionPlan设置目的地址。并且这里同时统计出了是否存在饥饿RegionServer(也就是RegionServer上Region数量没有达到min)。运行完成之后,集群中以及不存在没有设置RegionPlan目的地址了。此时集群情况如图10-9所示。

这里写图片描述

6)检查当前是否已经完成负载均衡的工作,也就是所有的RegionPlan是否全部设置了目的地址,如果已经全部分配了目的地址,这时集群的负载均衡工作已经完成。
7)如果第6步没有返回的话,这时表明还有RegionPlan未分配移动的目的地址,这时,首先检查第5步中是否存在饥饿RegionServer,如果存在,这时同样是从负载最高的RegionServer遍历,从每个RegionServer中摘除一个Region,直到满足能够将饥饿RegionServer填报为止。当然,上面的例子将不会出现这种情况。
8)如果这时还存在需要移动的Region没有安排目的地址,按照负载从小到大的顺序遍历RegionServer,如果遍历的RegionServer承载的Region数量不满max个,这时就能够重置Region的目的地址为该RegionServer,该遍历的终止条件是该RegionServer上的Region数量大于等于max。最终集群负载均衡完成后的情况如图10-10所示。

这里写图片描述

3.配置参数

hbase.balancer.period是设定负载均衡的参数,默认为每5分钟(300000毫秒)运行一次,参数配置通过hbase-site.xml文件。具体的设置格式如下:

<property>
<name>hbase.balancer.period</name>
<value>300000</value>
</property>

二、随机分配计划

在0.96版本中org.apache.hadoop.hbase.master.balancer类中不仅包含全局计划,也包含随机分配计划,即immediateAssignment。用于新加入的RegionServer,随机分配Region。随机函数使用java.util.Random类实现。其代码如下:

public Map<HRegionInfo, ServerName> immediateAssignment(List<HRegionInfo> regions,
      List<ServerName> servers) {
    metricsBalancer.incrMiscInvocations();

    Map<HRegionInfo, ServerName> assignments = new TreeMap<HRegionInfo, ServerName>();
    for (HRegionInfo region : regions) {
      assignments.put(region, randomAssignment(region, servers));
    }
    return assignments;
  }

三、批量启动分配计划

顾名思义,批量启动分配计划应用于集群启动时,决定Region分配到哪台机器,org.apache.hadoop.hbase.master.balancer类中包含两种批量启动分配计划:

retainAssignment : 保留分配。尝试使用META中的分配信息,有分配信息的按照原有分配信息分配Region,剩下的Region随机分配。
roundRobinAssignment : 循环分配。 使用floor(avg)和ceiling(avg)重新分配Region。


版权声明:本文为u013080251原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>