HBase RegionServer詳解

HBase RegionServer詳解

RegionServer組件介紹

RegionServer是HBase集羣運行在每個工作節點上的服務。它是整個HBase系統的關鍵所在,一方面它維護了Region的狀態,提供了對於Region的管理和服務;另一方面,它與Master交互,參與Master的分佈式協調管理。

MemStoreFlusher

MemStoreFlusher主要功能是將MemStore刷新到文件中,當滿足一下條件時會出發MemStore執行flush操作,最小的flush單元是region:

  • 當一個MemStore的大小等於hbase.hregion.memstore.flush.size指定大小時,所有屬於當前region的memstores都將寫入到文件;
  • 當MemStore使用內存總量達到hbase.regionserver.global.memstore.upperLimit指定值時,將會有多個MemStores flush到文件中,MemStore flush 順序是按照大小降序執行的,直到刷新到MemStore使用內存略小於hbase.regionserver.global.memstore.lowerLimit
  • 當每一個region server WAL數量達到hbase.regionserver.max.logs指定的值時,不同的region將按照時間先後順序flush memstores ,較早的將先被刷新,直到WAL數量低於hbase.regionserver.max.logs爲止。

    MemStoreFlusher的主要成員變量:

    class MemStoreFlusher implements FlushRequester {
    static final Log LOG = LogFactory.getLog(MemStoreFlusher.class);
    
    // These two data members go together.  Any entry in the one must have
    // a corresponding entry in the other.
    private final BlockingQueue<FlushQueueEntry> flushQueue =
    new DelayQueue<FlushQueueEntry>();
    private final Map<HRegion, FlushRegionEntry> regionsInQueue =
    new HashMap<HRegion, FlushRegionEntry>();
    private AtomicBoolean wakeupPending = new AtomicBoolean();
    
    private final long threadWakeFrequency;
    private final HRegionServer server;
    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    private final Object blockSignal = new Object();
    
    protected long globalMemStoreLimit;
    protected float globalMemStoreLimitLowMarkPercent;
    protected long globalMemStoreLimitLowMark;
    
    private long blockingWaitTime;
    private final Counter updatesBlockedMsHighWater = new Counter();
    
    private final FlushHandler[] flushHandlers;
    private List<FlushRequestListener> flushRequestListeners = new ArrayList<FlushRequestListener>(1);
  • flushQueue :代表某一個region 的Flush請求,Flusher線程不斷地從該隊列中獲取 請求信息,完成Region的Flush操作;
  • regionsInQueue :維護HRegion實例與請求FlushRegionEntry之間的對應關係;某一個FlushQueueEntry實例存在regionsInQueue 中也必然存在於flushQueue中 。
  • threadWakeFrequency:用於flushQueue執行poll操作時,最大等待時間,配置項爲hbase.server.thread.wakefrequency,默認值10000ms。

    MemStoreFlusher相關配置項:

HeapMemoryManager

CompactSplitThread

合併文件清理不需要的數據,控制Region的規模。在Store內的文件個數超過閾值時,觸發Compact合併文件操作,一是清理被刪除的數據,二是多餘版本的清理。在Region內的Store文件大小超過閾值,會觸發Region的Split操作,一個Region被切分成兩個Region。這兩個操作都是在CompactSplitThread的各自的線程池中被觸發。

ZooKeeperWatcher

MasterAddressTracker

捕獲Master服務節點的變化。HBase使用多Master來解決Master單點故障的問題,主Master服務故障時,它與ZooKeeper的心跳延遲超過閾值,ZooKeeeper路徑下的數據被清理,備Master上的ActiveMaserManager服務會競爭該Master路徑,成爲主Master。MasterAddresTracker是RS內部監聽Master節點變化的追蹤器。

ClusterStatusTracker

HBase集羣狀態追蹤器。該選項可以標識當前集羣的狀態,及它的啓動時間。該設置選項有利於集羣中的各個工作節點(RS)統一執行啓動和退出操作。

SplitLogWorker

基於Region的HLog文件切分器。在RS宕機之後,RS上的保存的HLog文件,需要按照Region進行切分。HMaster會把這些文件作爲任務放置到Zookeeper的splitlog路徑下,RS上SplitLogWorker會嘗試獲取任務,對獲取到的HLog文件按照Region進行分組,處理的結果保存到相應Region的recovered.edits目錄下。

RegionServer啓動過程分析

1.HRegionServer main方法
RegionServer是一個獨立的服務,有一個mian方法在啓動時被調用。mian方法內部調用HRegionServerCommandLine實現RegionServer的啓動。
具體代碼如下:

  public static void main(String[] args) throws Exception {
    VersionInfo.logVersion();
    Configuration conf = HBaseConfiguration.create();
    @SuppressWarnings("unchecked")
    Class<? extends HRegionServer> regionServerClass = (Class<? extends HRegionServer>) conf
        .getClass(HConstants.REGION_SERVER_IMPL, HRegionServer.class);

    new HRegionServerCommandLine(regionServerClass).doMain(args);
  }
  1. HRegionServer run方法

  2. HRegionServer preRegistrationInitialization方法
    此方法內部主要包括初始化zookeeper相關的服務以及RegionServer服務組件的初始化。

 private void preRegistrationInitialization(){
    try {
      setupClusterConnection();

      // Health checker thread.
      if (isHealthCheckerConfigured()) {
        int sleepTime = this.conf.getInt(HConstants.HEALTH_CHORE_WAKE_FREQ,
          HConstants.DEFAULT_THREAD_WAKE_FREQUENCY);
        healthCheckChore = new HealthCheckChore(sleepTime, this, getConfiguration());
      }
      this.pauseMonitor = new JvmPauseMonitor(conf);
      pauseMonitor.start();

      initializeZooKeeper();
      if (!isStopped() && !isAborted()) {
        initializeThreads();
      }
    } catch (Throwable t) {
      // Call stop if error or process will stick around for ever since server
      // puts up non-daemon threads.
      this.rpcServices.stop();
      abort("Initialization of RS failed.  Hence aborting RS.", t);
    }
  }

initializeThreads主要初始化RegionServer服務組件,主要包括初始化compactSplitThread,cacheFlusher,compactionChecker,以及Leases等。具體代碼如下:

  private void initializeThreads() throws IOException {
    // Cache flushing thread.
    this.cacheFlusher = new MemStoreFlusher(conf, this);

    // Compaction thread
    this.compactSplitThread = new CompactSplitThread(this);

    // Background thread to check for compactions; needed if region has not gotten updates
    // in a while. It will take care of not checking too frequently on store-by-store basis.
    this.compactionChecker = new CompactionChecker(this, this.threadWakeFrequency, this);
    this.periodicFlusher = new PeriodicMemstoreFlusher(this.threadWakeFrequency, this);
    this.leases = new Leases(this.threadWakeFrequency);

    // Create the thread to clean the moved regions list
    movedRegionsCleaner = MovedRegionsCleaner.createAndStart(this);

    if (this.nonceManager != null) {
      // Create the chore that cleans up nonces.
      nonceManagerChore = this.nonceManager.createCleanupChore(this);
    }

    // Setup RPC client for master communication
    rpcClient = RpcClientFactory.createClient(conf, clusterId, new InetSocketAddress(
        rpcServices.isa.getAddress(), 0));

    int storefileRefreshPeriod = conf.getInt(
        StorefileRefresherChore.REGIONSERVER_STOREFILE_REFRESH_PERIOD
      , StorefileRefresherChore.DEFAULT_REGIONSERVER_STOREFILE_REFRESH_PERIOD);
    if (storefileRefreshPeriod > 0) {
      this.storefileRefresher = new StorefileRefresherChore(storefileRefreshPeriod, this, this);
    }
    registerConfigurationObservers();
  }
發佈了87 篇原創文章 · 獲贊 224 · 訪問量 96萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章