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);
}
HRegionServer
run
方法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();
}