IT技术博客大学习 共学习 共进步

HBase中如何开发LoadBalance插件

搜索技术博客-淘宝 2012-05-17 23:34:55 浏览 2,603 次

    HBase 中的LoadBalancer策略控制了如何在集群启动时Assign所有用户Region到各个RegionServer上,以及如何定期检查Region分布情况并重新调整Region位置的。这些工作在0.92之前的版本中都是在HBase Master内核中实现的,开发人员如果希望扩展自己的LoadBalancer插件,只能Hack源码,但这随着社区版本的升级,Hack工作必须移植到新的版本中。幸好在0.92版本中,HBase将LoadBalancer策略从Master内核中抽取了出来,开放了LoadBalancer Interface,允许开发者根据自己的业务特定扩展自己的LoadBalancer插件。

    定制LoadBalancer插件需要两个步骤:

  • 继承org.apache.hadoop.hbase.master.LoadBalancer Interface,实现自己的LoadBalancer Class
  • 在hbase-site.xml中增加配置项,使得定制的LoadBalancer生效
  • hbase.master.loadbalancer.class

    {your custom loadbalancer class name}

        因此,开发LoadBalancer插件的前提准备工作便是清楚了解org.apache.hadoop.hbase.master.LoadBalancer这个Interface:

    public interface LoadBalancer extends Configurable {
    
    /**
    
    * Set the current cluster status.  This allows a LoadBalancer to map host name to a server
    
    * @param st
    
    */
    
    public void setClusterStatus(ClusterStatus st);
    
    //这个方法一般参考org.apache.hadoop.hbase.master.DefaultLoadBalancer即可,无需定制
    
    /**
    
    * Set the master service.
    
    * @param masterServices
    
    */
    
    public void setMasterServices(MasterServices masterServices);
    
    //这个方法一般参考org.apache.hadoop.hbase.master.DefaultLoadBalancer即可,无需定制
    
    /**
    
    * Perform the major balance operation
    
    * @param clusterState
    
    * @return List of plans
    
    */
    
    public List balanceCluster(Map> clusterState);
    
    //这个方法是HBase Master内部的balancer线程定期执行调用,用来定期检查并ReBalance集群
    
    /**
    
    * Perform a Round Robin assignment of regions.
    
    * @param regions
    
    * @param servers
    
    * @return Map of servername to regioninfos
    
    */
    
    public Map> roundRobinAssignment(List regions, List servers);
    
    //这个方法是HBase Master在启动时调用的,用来批量调度所有用户Region到RegionServer上(hbase.master.startup.retainassign设置为false时生效,与retainAssignment互斥)
    
    /**
    
    * Assign regions to the previously hosting region server
    
    * @param regions
    
    * @param servers
    
    * @return List of plans
    
    */
    
    public Map> retainAssignment(Map regions, List servers);
    
    //这个方法是HBase Master在启动时调用的,可以保持上次集群中Region的分布位置不变(hbase.master.startup.retainassign设置为true时生效,与roundRobinAssignment互斥)
    
    /**
    
    * Sync assign a region
    
    * @param regions
    
    * @param servers
    
    * @return Map regioninfos to servernames
    
    */
    
    public Map immediateAssignment(List regions, List servers);
    
    // 这个方法用来立即将目标regions进行assign,主要是要快速assign,可以暂时忽略均衡问题,交由balancer线程后续定期rebalance解决
    
    /**
    
    * Get a random region server from the list
    
    * @param servers
    
    * @return Servername
    
    */
    
    public ServerName randomAssignment(List servers);
    
    // 这个方法是在随机assign一个region时被调用,从当前live的regionservers中选取一个随机的server作为assignregion的目标,
    
    }

        在熟悉了LoadBalancer接口之后,我们可以开始创建一个自定义的LoadBalancer Class,实现定制化的Balance策略。HBase中默认的Balance策略是RegionServer级别的,即保证每个RegionServer中的Region数量均衡,但没有考虑到每个Table内部的Regions在所有RegionServers中的均衡,下图可以清晰的描述这个问题:

        由上图可以看出,各个RegionServer中的Regions数量是均衡的,但是每个Table内部都是不均衡的,因此各个Table的访问者很容易出现局部访问热点。我们定制Table Level的LoadBalancer不仅要实现RegionServer级别的Balance,同时也要实现Table级别的Balance,如下图所示:

        

        由上图可以看出,不仅RegionServer间保持均衡,每个Table内部的Region也是均匀分布的。具体实现TableLevelLoadBalancer是,要重点关注LoadBalancer Interface中的以下几个主要方法:

  • Map> roundRobinAssignment(List, List),HBase Master启动时将各个用户Table的Regions依次均匀assign到各个RegionServer中,这个可以参考DefaultLoadBalancer中的实现
  • Map> retainAssignment(Map regions, List servers), HBase Master启动时如果发现hbase.master.startup.retainassign设为true了,则不会进行roundRobinAssignment,而是调用这个方法保持上一次集群的region assign方案,这个方法也可以参考DefaultLoadBalancer中的实现
  • List balanceCluster(Map> clusterState),HBase Master中Balancer线程定期调用这个方法来进行ReBalance,这个方法是我们需要重点关注的,也是定制的关键,在这个方法中,我们主要进行了2个步骤:
  • 遍历当前各个table的regions在RegionServer中的分布情况,计算出各个table在每个RegionServer中应该的均匀region数量
  • 重新遍历当前各个table的regions在RegionServer中的分布情况,对于每个Table,根据第一步的计算出的均匀负载值,生成RegionPlan List,将每个RegionServer中超出均匀负载的region移到低于均匀负载的RegionServer中。在这个步骤中,同样需要保证每个RegionServer中总的Region数量是均衡的,这需要算法实现保证,稍有算法基础的开发人员应该可以很容易做到,这里就不细说了。
  • Map immediateAssignment(List regions, List servers),这个方法是用来快速assign region的,无需考虑复杂因素,因此这个方法也可以参考DefaultLoadBalancer中的实现,无需定制
  • ServerName randomAssignment(List servers), 这个方法是随机选择一个Live的RegionServer来作为assign的目标,因此这个方法也可以参考DefaultLoadBalancer中的实现
  •     至于LoadBalancer Interface中的其他几个方法,都是设置环境和配置信息的,因此完全拷贝DefaultLoadBalancer中的实现即可。

        本文主要介绍了HBase 0.92中如何开发LoadBalancer插件的方法,以及我们如何定制Table-Level的LoadBalancer插件。此外,还有一些其他的LoadBalancer插件思路也是不错的选择,例如:基于Region I/O负载的LoadBalancer插件,以及基于HDFS Block Locality的LoadBalancer插件,我们后续将进行更多的尝试和介绍

    建议继续学习

    1. HBase集群出现NotServingRegionException问题的排查及解决方法 (阅读 17,123)
    2. HFile存储格式 (阅读 15,822)
    3. hbase运维 (阅读 14,783)
    4. hbase介绍 (阅读 12,225)
    5. HBase技术介绍 (阅读 7,943)
    6. HBase随机写以及随机读性能测试 (阅读 7,424)
    7. HBase性能优化方法总结 (阅读 6,944)
    8. HBase二级索引与Join (阅读 6,861)
    9. HBase Thrift 接口使用注意事项 (阅读 6,602)
    10. Cassandra和HBase主要设计思路对比 (阅读 4,945)