zoukankan      html  css  js  c++  java
  • hbase中balance机制

              HBase是一种支持自动负载均衡的分布式KV数据库,在开启balance的开关(balance_switch)后,HBase的HMaster进程会自动根据指定策略挑选出一些Region,并将这些Region分配给负载比较低的RegionServer上。官方目前支持两种挑选Region的策略,一种叫做DefaultLoadBalancer,另一种叫做StochasticLoadBalancer,这两种策略后面会具体讲到。由于HBase的所有数据(包括HLog/Meta/HStoreFile等)都是写入到HDFS文件系统中的, 因此HBase的Region移动其实非常轻量级。在做Region移动的时候,保持这个Region对应的HDFS文件位置不变,只需要将Region的Meta数据分配到相关的RegionServer即可,整个Region移动的过程取决于RegionClose以及RegionOpen的耗时,这个时间一般都很短。

    本文来讲讲hbase的balance实现。

    balance的流程

    • 首先通过LoadBalancer找出所有需要移动的region plan,一个region plan包括region/原始RegionServer/目的RegionServer三个属性
    • unassign region , 将region从原来的RegionServer上解除绑定;
    • assign region ,将region绑定到目标RegionServer上;

         其中, unassign region的具体流程为:

    • create zk closing node . 该节点在/unassigned路径下, 包含(znode状态,region名字,原始RS名,payload)这些数据。
    • hmaster 调用rpc服务关闭region server。region-close的流程大致为先获取region的writeLock , 然后flush memstore, 再并发关闭该region下的所有的store file文件(注意一个region有多个store,每个store又有多个store file , 所以可以实现并发close store file) 。最后释放region的writeLock.
    • 设置zk closing node的znode状态为closed.

    assgin region的具体流程为:

    • 获取到对应的Region Plan.
    • HMaster调用rpc服务去Region Plan对应的RegionServer上open region. 这里会先更新/unassigned节点为opening. 然后并发Load HStore,再更行zk/ROOT/META表信息,这里是为了client下次能获取到正确的路由信息, 最后更新region状态为OPEN.

    DefaultLoadBalancer策略

    这种策略能够保证每个RS的regions个数基本上都相等,确切来说,假设一共有n个RS,第i个RS有Ai个region,记average=sigma(Ai)/n , 那么这种策略能够保证所有的RS的region个数都在[floor(average), ceil(average)]之间。这种策略的实现简单,应用广泛。

    但是,这种策略考虑的因素比较单一, 没有考虑到每台region server的读写qps/负载压力等等,这样就可能导致出现一种情况:虽然每个region server的regions都非常接近,但是90%的请求还是落在了一台RS上,因为这台RS上的region全部都是热点数据,这样还是没有达到负载均衡的目的。 但我觉得balance的首要目的是保证数据均衡,如果在数据均衡的情况下,负载还是集中,这时候就要考虑下rowKey的选择是否有问题了。因此, 我个人还是比较推荐采用DefaultLoadBalancer的。

    StochasticLoadBalancer策略

    StochasticLoadBalancer 这种策略真的是非常复杂,简单来讲,是一种综合权衡一下6个因素的均衡策略:

    • 每台服务器读请求数(ReadRequestCostFunction)
    • 每台服务器写请求数(WriteRequestCostFunction)
    • Region个数(RegionCountSkewCostFunction)
    • 移动代价(MoveCostFunction)
    • 数据locality(TableSkewCostFunction)
    • 每张表占据RegionServer中region个数上限(LocalityCostFunction)

    对于cluster的每一种region分布, 采用6个因素加权的方式算出一个代价值,这个代价值就用来评估当前region分布是否均衡,越均衡代价值越低。然后通过成千上万次随机迭代来找到一组RegionMove的序列,使得最终的代价值严格递减。 得到的这一组RegionMove就是HMaster最终执行的region迁移方案。

    这里用一段伪代码来描述这个迭代的过程:

    currentCost = MAX ; 
    plans  = []
    for(step = 0 ; step < 1000000; step ++ ){
        action = cluster.generateMove() 
        doAction( action );
        newCost  = computeCost(action) ;
        if (newCost < currentCost){
            currentCost = newCost;
        }else{
            undoAction(action);
        }
        plans.add( action )
    }

      其中generateMove()每次随机选择以下3种策略之一来生成RegionMove:

    1. 随机选择两个RS, 从每个RS中随机选择两个Region,然后生成一个Action, 这个Action有一半概率做RegionMove(从Region多的RS迁移到Region少的RS), 另一半概率做RegionSwap。
    2. 选择Region最多的RS和Region最少的RS,然后生成一个Action, 这个Action一半概率做RegionMove, 一半概率做RegionSwap。
    3. 随机找一个RS,然后找到该RS上数据locality最差的Region,然后找到Region大部分数据落在的RS,然后生成一个Action,该Action用来把Region迁移到它应该所在的RS,用来提高locality.

      对于这种策略,JavaDoc上说效果比较好,但其中的合理性个人觉得有待测试数据的证明(官方基本没有给出这方面的测试结果)。如果6个因素每个参数占据的权重如果没有调好的话,会导致线上的Region大量不均衡。按照我的一次线上经历,采用如下blance配置,出现过每次balance都只选择60个左右的plan去移动, 但真实的情况是145个RS,其中region数量最多的有700+个, 最少的region数量有2个,然后其他RS的region数量在2~700不等,这时候按理来讲应该需要进行大量的balance,但HMaster每隔一个period只生成60个plan左右去移动,这样balance太慢导致很长一段时间内负载不均,有的RS非常清闲,有的RS非常繁忙经常超时。

    hbase.master.loadbalancer.class=
        org.apache.hadoop.hbase.master.StochasticLoadBalancer
    hbase.master.balancer.stochastic.regionCountCost=10
    hbase.master.balancer.stochastic.tableSkewCost=5
    hbase.master.balancer.stochastic.readRequestCost=5
    hbase.master.balancer.stochastic.writeRequestCost=5
    hbase.master.balancer.stochastic.localityCost=10
    hbase.master.balancer.stochastic.moveCost=4
    hbase.master.balancer.stochastic.maxMovePercent=1

    后面对比了下了官方的默认配置,应该是regionCountCost一项权重太低, 但是,我想说的是除非线下有一个测试结果支撑具体的权重配置下 balance是符合预期的,否则线上操作时一般对权重很难有一个准确的把握,所以像这么复杂的策略还是要比较谨慎的选择,最好有过历史测试数据来评估balance的效果。

  • 相关阅读:
    Convolutional Neural Network-week1编程题(一步步搭建CNN模型)
    Coursera Deep Learning笔记 卷积神经网络基础
    爬取b站周杰伦新歌mv弹幕 绘制词云
    Coursera Deep Learning笔记 结构化机器学习项目 (下)
    Golang-执行go get私有库提示”410 Gone“ 解决办法
    golang常用的http请求操作
    关于asyncio知识(四)
    关于asyncio知识(二)
    Python Every Class Needs a __repr__
    关于asyncio知识(一)
  • 原文地址:https://www.cnblogs.com/xjh713/p/6909076.html
Copyright © 2011-2022 走看看