HBase深入分析之RegionServer

HBase深入分析之RegionServer

所有的用戶數據以及元數據的請求,在經過Region的定位,最終會落在RegionServer上,并由RegionServer實現數據的讀寫操作。本小節將重點介紹RegionServer的代碼結構和功能,從實現細節上深入理解RegionServer對于數據的操作流程。

1 RegionServer概述

RegionServer是HBase集群運行在每個工作節點上的服務。它是整個HBase系統的關鍵所在,一方面它維護了Region的狀態提供了對于Region的管理和服務;另一方面,它與Master交互,上傳Region的負載信息上傳,參與Master的分布式協調管理。具體如圖(1)所示。

圖(1) RegionServer的整體功能圖

HRegionServer與HMaster以及Client之間采用RPC協議進行通信。HRegionServer向HMaster定期匯報節點的負載狀況,包括RS內存使用狀態、在線狀態的Region等信息,在該過程中RS扮演了RPC客戶端的角色,而HMaster扮演了RPC服務器端的角色。RS內置的RpcServer實現了數據更新、讀取、刪除的操作,以及Region涉及到Flush、Compaction、Open、Close、Load文件等功能性操作。此時,RS扮演了RPC服務的服務端的角色。RS與Client之間的RPC是HBase最為核心的操作,其服務狀況的好壞,直接反映了RS內部、以及它所依賴的HDFS服務質量的好壞,因此,該過程的RPC經常成為分析讀寫性能異常的突破口。

從RegionServer實現的功能上而言,除了與HMaster和Client之間的RPC通信之外,還包括如下幾個重要的模塊:

(1)依托ZookeeperWatcher進行的分布式信息共享與任務協調的工作。

MasterAddressTracker:捕獲Master服務節點的變化。

HBase使用多Master來解決Master單點故障的問題,主Master服務故障時,它與ZooKeeper的心跳延遲超過閾值,ZooKeeeper路徑下的數據被清理,備Master上的ActiveMaserManager服務會競爭該Master路徑,成為主Master。

MasterAddresTracker是RS內部監聽Master節點變化的追蹤器。

([yù zhí]閾值,閾值又叫臨界值,是指一個效應能夠產生的最低值或最高值。閾值又稱閾強度,是指釋放一個行為反應所需要的最小刺激強度。低于閾值的刺激不能導致行為釋放。)

ClusterStatusTracker:HBase集群狀態追蹤器。

該選項可以標識當前集群的狀態,及它的啟動時間。

該設置選項有利于集群中的各個工作節點(RS)統一執行啟動和退出操作。

CatalogTracker:跟蹤-ROOT-、.META.表的Region的狀態。在HBase支持的-ROOT-、.META.、以及User Region三層樹級目錄結構中,-ROOT-、.META.表用來定位Region的位置,追蹤-ROOT-表和.META.表對應Region的變化,可以時刻保證整個層次目錄樹的完整性。

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

(2)Region的管理。

Region是HBase數據存儲和管理的基本單位。Client從.META.表的查找RowKey對應的Region的位置,每個Region只能被一個RS提供服務,RS可以同時服務多個Region,來自不同RS上的Region組合成表格的整體邏輯視圖。

圖(1) RegionServer的整體功能圖

RS內涉及到提供的有關Region維護的服務組件有:

1) MemStoreFlusher,控制RS的內存使用,有選擇性地將Region的MemStore數據寫入文件。該組件可以有效地控制RS的內存使用,flush文件的速度在一定程度上可以反應HBase寫服務的繁忙狀況。

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

3) CompactionChecker,周期性檢查RS上的Region是否需要進行Compaction操作,確認需要進行Compaction操作的Region,提交給CompactSplitThread執行請求。

RS的內存的使用分為MemStore和BlockCache。其中MemStore提供寫操作的緩存,而BlockCache是提供的讀請求緩存。它們詳細的內容會在后續章節中介紹。

(3)WAL的管理。

HBase對于數據的更新和刪除操作默認先Append到HLog文件,然后再更新到RS對應的Region上,因此,由HLog文件在RS的處理方式,被稱為Write-Ahead-Log。多個Region的更新刪除操作會被相繼寫入同一個文件,出于以下的原因,HLog文件會被截斷,然后創建新HLog文件繼續當前的Append操作。

1) Append操作失敗,避免因底層文件系統的文件異常,阻塞數據的操作。

2) 降低存儲空間的開銷。當HLog上記錄的數據完全從MemStore寫入HDFS,此時如果多個HLog文件,有利于篩選冗余的HLog文件,提高存儲空間的效率。

3) 提高分布式HLog文件切分操作(Distributed Log Split)的效率。多個HLog文件就對應同樣數目的LogSplit子任務,從而可以借助多個RS的SplitLogWorker組件快速完成HLog文件的切分,盡快恢復Region的服務。

在RS內,LogRoller定期刷新出一個新的HLog文件。

(4)Metrics

Metrics對外提供了衡量HBase內部服務狀況的參數。RegionServer內Metrics包含了內存使用、Region服務狀況、Compaction、blockCache等一系列標識服務狀況的參數。HBase Metrics繼承Hadoop Metrics的實現,目前支持文件、Ganglia、以及數據流等多種輸出方式,可以針對輸出的Metrics信息靈活構建監控系統

(5)HttpServer

RS內置了一個Jetty Web Server,用來對外提供RS的訪問頁面。訪問頁面目前支持實時Metrics信息查詢、日志查詢、線程的Dump、修改日志級別等操作。

2 RegionServer的啟動過程分析

RegionServer服務由org.apache.hadoop.hbase.regionserver.HRegionServer類提供。該類實現了四個接口,分別是HRegionInterface,RegionServerServices,HBaseRPCErrorHandler和Runnable。其中,

HRegionInterface定義了RS對外提供的RPC訪問接口,通過RPCServer內置的Handler來處理請求;

RegionServerServices定義了基于RS內部的服務信息接口,例如onlineRegions增、刪、查接口,以及獲取HLog、文件系統等接口;

HBaseRPCErrorHandler定義了RPCServer異常狀態檢測處理接口;

Runnable是Java庫中的線程接口,實現該接口意味著RegionServer生命周期會運行在run()的函數體內。

RegionServer是一個獨立的服務,有一個main函數在啟動時被調用,main函數內通過HRegionServerCommandLine的反射機制在JVM內動態加載RegionServer實現類,并按照args解析參數情況,決定啟動或者關閉RS服務。

?View CodeJAVA

publicclassHRegionServerimplementsHRegionInterface,HBaseRPCErrorHandler,Runnable,RegionServerServices{...//成員變量定義和成員函數實現publicstaticvoidmain(String[]args)throwsException{...Configurationconf=HBaseConfiguration.create();@SuppressWarnings("unchecked")ClassregionServerClass=(Class)conf.getClass(HConstants.REGION_SERVER_IMPL, HRegionServer.class);//獲取RegionServer對應的類newHRegionServerCommandLine(regionServerClass).doMain(args);//創建RegionServer實例并啟動}...}

初始化與執行過程包括:

(1)構造HRegionServer實例,初始化變量和對象。這涉及到以下重要變量初始化:

protected volatile boolean stopped = false;//關閉Server的標識,關閉過程中會置成ture

private boolean stopping = false;//關閉Region過程的標識,是進入stopped之前的狀態

protected volatile boolean fsOk;//文件系統狀態標識,false表示文件系統不可用

private final ConcurrentSkipListMap regionsInTransitionInRS =

new ConcurrentSkipListMap(Bytes.BYTES_COMPARATOR);//RS內處于遷移過程中的Region,其中true表示在open,false表示在close

protected final Map onlineRegions =

new ConcurrentHashMap();//RS內正在服務的Region

protected final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();//修改onlineRegions對象的讀寫鎖

protected final int threadWakeFrequency;//工作線程服務周期間隔

private final int msgInterval;//向Master匯報心跳,收集Metrics間隔

private final long maxScannerResultSize;//Scanner執行next返回的數據量閾值,默認設置是Long.MAX_VALUE

private int webuiport = -1;//webServer的端口號

private final long startcode;//HRegiongServer初始化的時間,取自系統時間

private ServerName serverNameFromMasterPOV;//標識Server的名字

private final int rpcTimeout;//定義到HMaster之間的rpc超時時間

在RS上重要的對象列表,如表1所示。

表1RegionServer重要對象的解釋

對象名對應類名功能描述

(2)監聽服務組件的初始化與執行。

這個過程初始化以ZooKeeperWatcher為基礎的服務,例如監聽Master服務節點的MasterAddressManager,標識HBase集群狀態的ClusterStatusTracker,以及元數據(-ROOT-, .META.)變化的監聽器。啟動這些服務可以保證整個集群信息協調一致。

(3)RS服務組件的初始化與執行。

這個過程是初始化compactSplitThread,cacheFlusher,compactionChecker,以及Leases。

(4)嘗試連接HMaster,注冊RS到HMaster。

(5)周期性收集Metrics和向Master發送心跳。

3 Store相關

Region是RS上的基本數據服務單位,用戶表格由1個或者多個Region組成,根據Table的Schema定義,在Region內每個ColumnFamily的數據組成一個Store。每個Store內包括一個MemStore和若干個StoreFile(HFile)組成。如圖(3)所示。本小節將介紹Store內的MemStore、StoreFile(HFile)的內部結構與實現。

圖(3) Region-Store結構圖

3.1 MemStore原理與實現分析

MemStore是一個內存區域,用以緩存Store內最近一批數據的更新操作。對于Region指定的ColumnFamily下的更新操作(Put、Delete),首先根據是否寫WriteAheadLog,決定是否append到HLog文件,然后更新到Store的MemStore中。顯然,MemStore的容量不會一直增長下去,因此,在每次執行更新操作時,都會判斷RS上所有的MemStore的內存容量是否超過閾值,如果超過閾值,通過一定的算法,選擇Region上的MemStore上的數據Flush到文件系統。更詳細的處理流程圖如圖(4)。

圖(4) 更新操作的流程圖

MemStore類內的重要的成員變量:

?View CodeJAVA

volatileKeyValueSkipListSet kvset;//內存中存放更新的KV的數據結構volatileKeyValueSkipListSet snapshot;//Flush操作時的KV暫存區域finalReentrantReadWriteLock lock=newReentrantReadWriteLock();//Flush操作與kvset之間的可重入讀寫鎖finalAtomicLong size;//跟蹤記錄MemStore的占用的Heap內存大小TimeRangeTracker timeRangeTracker;//跟蹤記錄kvset的最小和最大時間戳TimeRangeTracker snapshotTimeRangeTracker;//跟蹤記錄snapshot的最小和最大時間戳MemStoreLAB allocator;//實際內存分配器

注意:

KeyValueSkipListSet是對于jdk提供的ConcurrentSkipListMap的封裝,Map結構是的形式。Concurrent表示線程安全。SkipList是一種可以代替平衡樹的數據結構,默認是按照Key值升序的。對于ConcurrentSkipListMap的操作的時間復雜度平均在O(logn),設置KeyValue.

KVComparator比較KeyValue中Key的順序。

寫入MemStore中的KV,被記錄在kvset中。根據JVM內存的垃圾回收策略,在如下條件會觸發Full GC。

? 內存滿或者觸發閾值。

? 內存碎片過多,造成新的分配找不到合適的內存空間。

RS上服務多個Region,如果不對KV的分配空間進行控制的話,由于訪問的無序性以及KV長度的不同,每個Region上的KV會無規律地分散在內存上。Region執行了MemStore的Flush操作,再經過JVM GC之后就會出現零散的內存碎片現象,而進一步數據大量寫入,就會觸發Full-GC。圖(5)顯示這種假設場景的內存分配過程。

圖(5) 無處理狀態下MemStore內存分配圖

為了解決因為內存碎片造成的Full-GC的現象,RegionServer引入了MSLAB(HBASE-3455)。MSLAB全稱是MemStore-Local Allocation Buffers。它通過預先分配連續的內存塊,把零散的內存申請合并,有效改善了過多內存碎片導致的Full GC問題。

MSLAB的工作原理如下:

? 在MemStore初始化時,創建MemStoreLAB對象allocator。

? 創建一個2M大小的Chunk數組,偏移量起始設置為0。Chunk的大小可以通過參數hbase.hregion.memstore.mslab.chunksize調整。

? 當MemStore有KeyValue加入時,maybeCloneWithAllocator(KeyValue)函數調用allocator為其查找KeyValue.getBuffer()大小的空間,若KeyValue的大小低于默認的256K,會嘗試在當前Chunk下查找空間,如果空間不夠,MemStoreLAB重新申請新的Chunk。選中Chunk之后,會修改offset=原偏移量+KeyValue.getBuffer().length。chunk內控制每個KeyValue大小由hbase.hregion.memstore.mslab.max.allocation配置。

? 空間檢查通過的KeyValue,會拷貝到Chunk的數據塊中。此時,原KeyValue由于不再被MemStore引用,會在接下來的JVM的Minor GC被清理。

注意:

設置chunk的默認大小以及對于KeyValue大小控制的原因在于,MSLAB雖然會降低內存碎片造成的Full-GC的風險,但是它的使用會降低內存的利用率。如果超過一定大小的KeyValue,此時該KeyValue空間被回收之后,碎片現象不明顯。因此,MSLAB只解決小KV的聚合。

MSLAB解決了因為碎片造成Full GC的問題,然而在MemStore被Flush到文件系統時,沒有reference的chunk,需要GC來進行回收,因此,在更新操作頻繁發生時,會造成較多的Young GC。

針對該問題,HBASE-8163提出了MemStoreChunkPool的解決方案,方案已經被HBase-0.95版本接收。它的實現思路:

? 創建chunk池來管理沒有被引用的chunk,不再依靠JVM的GC回收。

? 當一個chunk沒有引用時,會被放入chunk池。

? chunk池設置閾值,如果超過了,則會放棄放入新的chunk到chunk池。

? 如果當需要新的chunk時,首先從chunk池中獲取。

根據patch的測試顯示,配置MemStoreChunkPool之后,YGC降低了40%,寫性能有5%的提升。如果是0.95以下版本的用戶,可以參考HBASE-8163給出patch。

思考

通過MemStore提供的MSLAB和MemStoreChunkPool給出的解決方案,可以看出在涉及到大規模內存的Java應用中,如何有效地管理內存空間,降低JVM

GC對于系統性能造成的影響,成為了一個研究熱點。整體上來說,一是設置與應用相適應的JVM啟動參數,打印GC相關的信息,實時監控GC對于服務的影響;二是從應用程序設計層面,盡可能地友好地利用內存,來降低GC的影響。

在ChunkPool就是幫助JVM維護了chunk信息,并把那些已經不再MemStore中的數據的chunk重新投入使用。這樣就可以避免大量的YGC。

3.2 MemStore參數控制原理與調優

對于任何一個HBase集群而言,都需要根據應用特點對其系統參數進行配置,以達到更好的使用效果。MemStore作為更新數據的緩存,它的大小及處理方式的調整,會極大地影響到寫數據的性能、以及隨之而來的Flush、Compaction等功能。這種影響的原因在于以下兩個方面。

? RS全局的MemStore的大小與Region規模以及Region寫數據頻度之間的關系。

? 過于頻繁的Flush操作對于讀數據的影響。

這其中涉及到的可調整的參數如下表。

表MemStore相關的配置參數

參數名稱參數含義默認值

hbase.regionserver.global.memstore.upperLimitRS內所有MemStore的總和的上限/Heap Size的比例,超過該值,阻塞update,強制執行Flush操作。0.4

hbase.regionserver.global.memstore.lowerLimit執行Flush操作釋放內存空間,需要達到的比例。0.35

hbase.hregion.memstore.flush.size每個MemStore占用空間的最大值,超過該值會執行Flush操作。128MB

hbase.hregion.memstore.block.multiplierHRegion的更新被阻塞的MemStore容量的倍數。2

hbase.hregion.preclose.flush.size關閉Region之前需要執行Flush操作的MemStore容量閾值。5MB

對于上述參數理解:

(1)RS控制內存使用量的穩定。

例如,假設我們的RS的內存設置為10GB,按照以上參數的默認值,RS用以MemStore的上限為4GB,超出之后,會阻塞整個RS的所有Reigon的請求,直到全局的MemStore總量回落到正常范圍之內。

以上涉及到cacheFlusher在MemStore總量使用超過上限時,選擇Region進行Flush的算法,由MemStoreFlusher.flushOneForGlobalPressure()算法實現。算法的處理流程如下。

關鍵的數據結構:

?View CodeJAVA

SortedMapregionsBySize=server.getCopyOfOnlineRegionsSortedBySize();//從RS上獲取在線的Region,以及它們在MemStore上使用量,并按照MemStore使用量作為Key,降序。SetexcludedRegions=newHashSet();//記錄嘗試執行Flush操作失敗的Region…HRegion bestFlushableRegion=getBiggestMemstoreRegion(regionsBySize, excludedRegions,true);//選出storefile個數不超標、當前MemStore使用量最大的RegionHRegion bestAnyRegion=getBiggestMemstoreRegion(regionsBySize, excludedRegions,false);//選出當前MemStore使用量最大的Region

步驟1:RS上在線的Region,按照當前MemStore的使用量進行排序,并存儲在regionsBySize中。

步驟2:選出Region下的Store中的StoreFile的個數未達到hbase.hstore.blockingStoreFiles,并且MemStore使用量最大的Region,存儲到bestFlushableRegion。

步驟3:選出Region下的MemStore使用量最大的Region,存儲到bestAnyRegion對象。

步驟4:如果bestAnyRegion的memstore使用量超出了bestFlushableRegion的兩倍,這從另外一個角度說明,雖然當前bestAnyRegion有超過blockingStoreFiles個數的文件,但是考慮到RS內存的壓力,冒著被執行Compaction的風險,也選擇這個Region作為regionToFlush,因為收益大。否則,直接選擇bestFlushableRegion作為regionToFlush。

步驟5:對regionToFlush執行flush操作。如果操作失敗,regionToFlush放入excludedRegions,避免該Region下次再次被選中,然后返回步驟2執行,否則程序退出。

(2)設置兩個limit,盡可能減少因為控制內存造成數據更新流程的阻塞。

當RS的MemStore使用總量超過(Heap*hbase.regionserver.global.memstore.lowerLimit)的大小時,同樣會向cacheFlusher提交一個Flush請求,并以(1)中Region選擇算法,對其進行Flush操作。與(1)不同,這個過程中RS不會阻塞RS的寫請求。

因此,在生產環境中,我們肯定不希望更新操作被block,一般會配置(upperLimit –lowerlimit)的值在[0.5,0.75]之間,如果是應用寫負載較重,可以設置區間內較大的值。

3.3 StoreFile—HFile

該節請參考:HFile文件格式與HBase讀寫

3.4 Compaction對于服務的影響

該小節請參考:深入分析HBase Compaction機制

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容

  • 簡介 [HBase]——Hadoop Database的簡稱,Google BigTable的另一種開源實現方式,...
    高廣超閱讀 2,371評論 1 27
  • HBase存儲架構圖 HBase Master 為Region server分配region 負責Region s...
    kimibob閱讀 5,610評論 0 52
  • 該文檔是用Hbase默認配置文件生成的,文件源是Hbase-default.xml hbase.rootdir 這...
    我是嘻哈大哥閱讀 4,801評論 0 7
  • HBase那些事 @(大數據工程學院)[HBase, Hadoop, 優化, HadoopChen, hbase]...
    分癡閱讀 3,974評論 3 17
  • 最近在逐步跟進Hbase的相關工作,由于之前對Hbase并不怎么了解,因此系統地學習了下Hbase,為了加深對Hb...
    飛鴻無痕閱讀 50,303評論 19 272