1. 程式人生 > >HBase 1.1.3 balance相關原始碼分析 一

HBase 1.1.3 balance相關原始碼分析 一

HMaster類中與balance相關部分


1、初始化

//balancer作為HMaster的一個成員變數
LoadBalancer balancer;  
//ClusterStatusChore 這個會定時去執行balancer
private ClusterStatusChore clusterStatusChore;

//在HMaster的initializeZKBasedSystemTrackers中函式例項化一個balancer
//具體為LoadBalancerFactory.getLoadBalancer得到一個balancer例項(預設是得到StochasticLoadBalancer型別的balancer,如果有配置hbase.master.loadbalancer.class,則例項化一個這個配置對應的類例項)
this.balancer = LoadBalancerFactory.getLoadBalancer(conf);

//在HMster的finishActiveMasterInitialization函式中初始化balancer
//initialize load balancer
    this.balancer.setClusterStatus(getClusterStatus());
    this.balancer.setMasterServices(this);
    this.balancer.initialize();

//定時任務去呼叫執行balancer,如果沒有配置hbase.balancer.statusPeriod則是間隔時間是60000,
//如果配置了則按照配置的hbase.balancer.statusPeriod時間。
    this.clusterStatusChore = new ClusterStatusChore(this, balancer);
	getChoreService().scheduleChore(clusterStatusChore);

2、balance函式
//在HMaster中有一個balance函式


  public boolean balance() throws IOException {
    // if master not initialized, don't run balancer.
    if (!this.initialized) {
      LOG.debug("Master has not been initialized, don't run balancer.");
      return false;
    }
    // Do this call outside of synchronized block.
    int maximumBalanceTime = getBalancerCutoffTime();
    synchronized (this.balancer) {
      // If balance not true, don't run balancer.
      if (!this.loadBalancerTracker.isBalancerOn()) return false;
      // Only allow one balance run at at time.
      if (this.assignmentManager.getRegionStates().isRegionsInTransition()) {
        Map<String, RegionState> regionsInTransition =
          this.assignmentManager.getRegionStates().getRegionsInTransition();
        LOG.debug("Not running balancer because " + regionsInTransition.size() +
          " region(s) in transition: " + org.apache.commons.lang.StringUtils.
            abbreviate(regionsInTransition.toString(), 256));
        return false;
      }
      if (this.serverManager.areDeadServersInProgress()) {
        LOG.debug("Not running balancer because processing dead regionserver(s): " +
          this.serverManager.getDeadServers());
        return false;
      }


      if (this.cpHost != null) {
        try {
			//this.cpHost.preBalance()裡面會觸發BaseMasterObserver中的 
			//preBalance(ObserverContext<MasterCoprocessorEnvironment> ctx)
          if (this.cpHost.preBalance()) {
            LOG.debug("Coprocessor bypassing balancer request");
            return false;
          }
        } catch (IOException ioe) {
          LOG.error("Error invoking master coprocessor preBalance()", ioe);
          return false;
        }
      }
		//this.assignmentManager.getRegionStates().getAssignmentsByTable()會根據配置如果配置的是
		//hbase.master.loadbalance.bytable為true則返回結構每個表會有一個mapentry(TableName就是表的名稱)
		//如果沒有配置hbase.master.loadbalance.bytable或者為false則所有表會返回一個mapentry(表名為TableName.valueOf("ensemble"))
      Map<TableName, Map<ServerName, List<HRegionInfo>>> assignmentsByTable =
        this.assignmentManager.getRegionStates().getAssignmentsByTable();


      List<RegionPlan> plans = new ArrayList<RegionPlan>();
      //Give the balancer the current cluster state.
      this.balancer.setClusterStatus(getClusterStatus());
      for (Map<ServerName, List<HRegionInfo>> assignments : assignmentsByTable.values()) {
        List<RegionPlan> partialPlans = this.balancer.balanceCluster(assignments);
        if (partialPlans != null) plans.addAll(partialPlans);
      }
      long cutoffTime = System.currentTimeMillis() + maximumBalanceTime;
      int rpCount = 0;  // number of RegionPlans balanced so far
      long totalRegPlanExecTime = 0;
      if (plans != null && !plans.isEmpty()) {
        for (RegionPlan plan: plans) {
          LOG.info("balance " + plan);
          long balStartTime = System.currentTimeMillis();
          //TODO: bulk assign
          this.assignmentManager.balance(plan);
          totalRegPlanExecTime += System.currentTimeMillis()-balStartTime;
          rpCount++;
          if (rpCount < plans.size() &&
              // if performing next balance exceeds cutoff time, exit the loop
              (System.currentTimeMillis() + (totalRegPlanExecTime / rpCount)) > cutoffTime) {
            //TODO: After balance, there should not be a cutoff time (keeping it as a security net for now)
            LOG.debug("No more balancing till next balance run; maximumBalanceTime=" +
              maximumBalanceTime);
            break;
          }
        }
      }
      if (this.cpHost != null) {
        try {
          this.cpHost.postBalance(rpCount < plans.size() ? plans.subList(0, rpCount) : plans);
        } catch (IOException ioe) {
          // balancing already succeeded so don't change the result
          LOG.error("Error invoking master coprocessor postBalance()", ioe);
        }
      }
    }
    // If LoadBalancer did not generate any plans, it means the cluster is already balanced.
    // Return true indicating a success.
    return true;
  }


  
  


  
  
  

相關推薦

HBase 1.1.3 balance相關原始碼分析

HMaster類中與balance相關部分1、初始化//balancer作為HMaster的一個成員變數 LoadBalancer balancer; //ClusterStatusChore 這個會定時去執行balancer private ClusterStatus

QEMU1.3.0的原始碼分析 : 原始碼目錄簡介

最近在研究QEMU,讀了一些QEMU的原始碼,因為涉及的東西比較多,找到的資料又都比較破碎,不太完整。所以將最近的成果總結一下。相比其他的開源軟體來說,QEMU原始碼下面目錄比較多,下面就先把這些目錄的內容大致整理一下。docs/ 包含了一些文件,說實話,對初學者來說,讀這

Android7.1 [Camera] cam_board.xml 檔案解析原始碼分析()

        原始碼平臺:rk3399           RK支援了很多個攝像頭,在驅動目錄hardware/rockchip/camer

Redisson3.6.1版本的分散式鎖原始碼分析

前言:    stringRedisTemple好像沒有做到unlock的時候只解鎖當前執行緒的鎖,redisson看原始碼會獲取ThreadId,就想找找原始碼解讀,一直沒找到,google了一下才找到,轉載一下哈哈哈哈!最近碰到的一個問題,Java程式碼中寫了一個定時器,

ernel 3.10核心原始碼分析--KVM相關--虛擬機器執行

1、基本原理 KVM虛擬機器通過字元裝置/dev/kvm的ioctl介面建立和執行,相關原理見之前的文章說明。 虛擬機器的執行通過/dev/kvm裝置ioctl VCPU介面的KVM_RUN指令實現,在VM和VCPU建立好並完成初始化後,就可以排程該虛擬機器運行了,通

Java容器深入研究(jdk 1.8)--- ArrayList總結與原始碼分析

結構:public class ArrayList<E> extends AbstractList<E>   implements List<E>, RandomAccess, Cloneable, java.io.Serializabl

Shiro-1-原始碼分析設計模式(簡單工廠)

這裡先看看使用的原始碼 可以認為是資料庫的shiro.ini資料 格式:賬戶=密碼 [users] zhang=123 wang=123 主要程式碼 /** * @aut

5.1 Spring5原始碼--Spring AOP原始碼分析

目標: 1.什麼是AOP, 什麼是AspectJ, 2. 什麼是Spring AOP 3. Spring AOP註解版實現原理 4. Spring AOP切面原理解析  一. 認識AOP 1.1 什麼是AOP aop是面向切面程式設計,相比傳統oop,aop能夠在方法的前置,中置,後置中插入邏輯程

DispatcherServlet執行流程及相關原始碼分析

DispatcherServlet執行流程及相關原始碼分析 在前一篇文章SpringMVC 啟動流程及相關原始碼分析中,詳細探討了Spring MVC在Web容器中部署後的啟動過程,以及相關原始碼分析,同時也討論了DispatcherServlet類的初始化建立過程,相關內容在此不再贅述,如有需

presto UI 分析相關原始碼分析

CLUSTER OVERVIEW RESERVED MEMORY QUERY DETAILS

Android進階3:Activity原始碼分析(2) —— Activity啟動和銷燬流程(8.0)

上篇文章講述了app從啟動建立Activity呼叫onCreate,onStart, onResume方法,這篇文章講述一下Activity啟動的另一個切入點:startActivity方法,啟動Activity。 通過上一篇文章,我們總結一下: 1:A

3.24 vchain原始碼分析2

接下來是合約的第二部分,直接上程式碼,註釋都在程式碼中 // Contract to sell and distribute VEN tokens // 分發VEN 代幣 contract VENSale is Owned{ /// chart of stage t

Executor相關原始碼分析

Executor是一個用來執行提交的任務(Runnable)的物件。這個介面提供了一種將任務的提交和任務如何去執行解耦機制 Executor詳解 先來檢視Executor的介面定義: public interface Executor {

Android事件分發(3)--ViewGroup原始碼分析

一、ViewGroup的onInterceptTouchEvent原始碼分析 onInterceptTouchEvent比較簡單先看他的原始碼 public boolean onInterceptTouchEvent(MotionEvent ev

Android攝像頭相關原始碼分析: 裝置驅動, HAL, Framework

Hardware的分析可以自底向上, 首先看V4L2Camera, 再看CameraHardware, 再到CameraFactory. Framework的程式碼自底向上看東西就太多了, 因此先從SDK中的攝像頭部分看起. HAL和Framework說的都是C++的東西, 實現了安卓的底層. 但是實際上

Linux Kernel 3.10核心原始碼分析--塊裝置層request plug/unplug機制

一、基本原理Linux塊裝置層使用了plug/unplug(蓄流/洩流)的機制來提升IO吞吐量。基本原理為:當IO請求提交時,不知直接提交給底層驅動,而是先將其放入一個佇列中(相當於水池),待一定時機或週期後再將該佇列中的請求統一下發。將請求放入佇列的過程即plug(蓄流)

Netty服務端啟動過程相關原始碼分析

1、Netty 是怎麼建立服務端Channel的呢? 我們在使用ServerBootstrap.bind(埠)方法時,最終呼叫其父類AbstractBootstrap中的doBind方法,相關原始碼如下: private ChannelFuture doBind(final SocketAddress lo

3、Spring原始碼分析3之載入Bean

1、Bean的載入 // 前面兩篇已經分析了讀取配置檔案,並註冊BeanDefinition BeanFactory bf = n

NSQ原始碼分析()——nsqd的初始化及啟動流程

nsq原始碼地址:https://github.com/nsqio/nsq 版本1.1.0  NSQ原始碼分析系列是我通過閱讀nsq的原始碼及結合網上的相關文章整理而成,由於在網上沒有找到很詳細和完整的文章,故自己親自整理了一份。如果有錯誤的地方,還請指正,希望這系列的文章給您帶來

CTS 原始碼分析() --CTS概況

1、什麼是CTS?      Compatibility Test Suite 相容性測試套件 說白了,就是一套工具。一套軟體組成的測試工具。 2、哪裡有這套工具?       &nb