HBase性能優化徹底版

近期在處理HBase的業務方面經常遇到各類瓶頸,一天大概一億條數據,在HBase性能調優方面進行相關配置和調優後取得了必定的成效,因而,特此在這裏總結了一下關於HBase全面的配置,主要參考個人另外兩篇文章:java

(1)http://blog.csdn.net/u014297175/article/details/47975875node

(2)http://blog.csdn.net/u014297175/article/details/47976909算法

在其基礎上總結出來的性能優化方法。數據庫

1.垃圾回收優化緩存

Java自己提供了垃圾回收機制,依靠JRE對程序行爲的各類假設進行垃圾回收,可是HBase支持海量數據持續入庫,很是佔用內存,所以繁重的負載會迫使內存分配策略沒法安全地依賴於JRE的判斷:須要調整JRE的參數來調整垃圾回收策略。有關java內存回收機制的問題具體請參考:http://my.oschina.net/sunnywu/blog/332870安全

(1)HBASE_OPTS或者HBASE_REGIONSERVER_OPT變量來設置垃圾回收的選項,後面通常是用於配置RegionServer的,須要在每一個子節點的HBASE_OPTS文件中進行配置。性能優化

1)首先是設置新生代大小的參數,不能太小,太小則致使年輕代過快成爲老生代,引發老生代產生內存隨便。一樣不能過大,過大致使全部的JAVA進程中止時間長。-XX:MaxNewSize=256m-XX:NewSize=256m 這兩個能夠合併成爲-Xmn256m這一個配置來完成。服務器

2)其次是設置垃圾回收策略:-XX:+UseParNewGC -XX:+UseConcMarkSweepGC也叫收集器設置。session

3)設置CMS的值,佔比多少時,開始併發標記和清掃檢查。-XX:CMSInitiatingOccupancyFraction=70併發

4)打印垃圾回收信息:-verbose:gc -XX: +PrintGCDetails -XX:+PrintGCTimeStamps

-Xloggc:$HBASE_HOME/logs/gc-$(hostname)-hbase.log

最終能夠獲得:HBASE_REGIONSERVER_OPT="-Xmx8g -Xms8g –Xmn256m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC  \

-XX:CMSInitiatingOccupancyFraction=70   -verbose:gc \

-XX:+PrintGCDetails -XX:+PrintGCTimeStamps \

-Xloggc:$HBASE_HOME/logs/gc-$(hostname)-hbase.log

(2)hbase.hregion.memstore.mslab.enabled默認值:true,這個是在hbase-site.xml中進行配置的值。

說明:減小因內存碎片致使的Full GC,提升總體性能。

2.啓用壓縮,詳情自行搜索,暫時不曾嘗試,後面持續更新。

3.優化Region拆分合並以及與拆分Region

(1)hbase.hregion.max.filesize默認爲256M(在hbase-site.xml中進行配置),當region達到這個閾值時,會自動拆分。能夠把這個值設的無限大,則能夠關閉HBase自動管理拆分,手動運行命令來進行region拆分,這樣能夠在不一樣的region上交錯運行,分散I/O負載。

(2)預拆分region

用戶能夠在建表的時候就制定好預設定的region,這樣就能夠避免後期region自動拆分形成I/O負載。

4.客戶端入庫調優

(1)用戶在編寫程序入庫時,HBase的自動刷寫是默認開啓的,即用戶每一次put都會提交到HBase server進行一次刷寫,若是須要高速插入數據,則會形成I/O負載太重。在這裏能夠關閉自動刷寫功能,setAutoFlush(false)。如此,put實例會先寫到一個緩存中,這個緩存的大小經過hbase.client.write.buffer這個值來設定緩存區,當緩存區被填滿以後纔會被送出。若是想要顯示刷寫數據,能夠調用flushCommits()方法。

此處引伸:採起這個方法要估算服務器端內存佔用則能夠:hbase.client.write.buffer*hbase.regionserver.handler.count得出內存狀況。

(2)第二個方法,是關閉每次put上的WAL(writeToWAL(flase))這樣能夠刷寫數據前,不須要預寫日誌,可是若是數據重要的話建議不要關閉。

(3)hbase.client.scanner.caching:默認爲1

這是設計客戶端讀取數據的配置調優,在hbase-site.xml中進行配置,表明scanner一次緩存多少數據(從服務器一次抓取多少數據來scan)默認的過小,可是對於大文件,值不該太大。

(4)hbase.regionserver.lease.period默認值:60000

說明:客戶端租用HRegion server 期限,即超時閥值。

調優:這個配合hbase.client.scanner.caching使用,若是內存夠大,可是取出較多數據後計算過程較長,可能超過這個閾值,適當可設置較長的響應時間以防被認爲宕機。

(5)還有諸多實踐,如設置過濾器,掃描緩存等,指定行掃描等多種客戶端調優方案,須要在實踐中慢慢挖掘。

5.HBase配置文件

上面涉及到的調優內容或多或少在HBase配置文件中都有所涉及,所以,下面的配置不涵蓋上面已有的配置。

(1) zookeeper.session.timeout(默認3分鐘)

ZK的超期參數,默認配置爲3分鐘,在生產環境上建議減少這個值在1分鐘或更小。

設置原則:這個值越小,當RS故障時Hmaster獲知越快,Hlog分裂和region 部署越快,集羣恢復時間越短。 可是,設置這個值得原則是留足夠的時間進行GC回收,不然會致使頻繁的RS宕機。通常就作默認便可

(2)hbase.regionserver.handler.count(默認10)

對於大負載的put(達到了M範圍)或是大範圍的Scan操做,handler數目不易過大,易形成OOM。 對於小負載的put或是get,delete等操做,handler數要適當調大。根據上面的原則,要看咱們的業務的狀況來設置。(具體狀況具體分析)。

(3)HBASE_HEAPSIZE(hbase-env.sh中配置)

個人前兩篇文章Memstoresize40%(默認) blockcache 20%(默認)就是依據這個而成的,整體HBase內存配置。設到機器內存的1/2便可。

(4)選擇使用壓縮算法,目前HBase默認支持的壓縮算法包括GZ,LZO以及snappy(hbase-site.xml中配置)

(5)hbase.hregion.max.filesize默認256M

上面說過了,hbase自動拆分region的閾值,能夠設大或者無限大,無限大須要手動拆分region,懶的人別這樣。

(6)hbase.hregion.memstore.flush.size

單個region內全部的memstore大小總和超過指定值時,flush該region的全部memstore。

(7)hbase.hstore.blockingStoreFiles  默認值:7

說明:在flush時,當一個region中的Store(CoulmnFamily)內有超過7個storefile時,則block全部的寫請求進行compaction,以減小storefile數量。

調優:block寫請求會嚴重影響當前regionServer的響應時間,但過多的storefile也會影響讀性能。從實際應用來看,爲了獲取較平滑的響應時間,可將值設爲無限大。若是能容忍響應時間出現較大的波峯波谷,那麼默認或根據自身場景調整便可。

(8)hbase.hregion.memstore.block.multiplier默認值:2

說明:當一個region裏總的memstore佔用內存大小超過hbase.hregion.memstore.flush.size兩倍的大小時,block該region的全部請求,進行flush,釋放內存。

雖然咱們設置了region所佔用的memstores總內存大小,好比64M,但想象一下,在最後63.9M的時候,我Put了一個200M的數據,此時memstore的大小會瞬間暴漲到超過預期的hbase.hregion.memstore.flush.size的幾倍。這個參數的做用是當memstore的大小增至超過hbase.hregion.memstore.flush.size 2倍時,block全部請求,遏制風險進一步擴大。

調優: 這個參數的默認值仍是比較靠譜的。若是你預估你的正常應用場景(不包括異常)不會出現突發寫或寫的量可控,那麼保持默認值便可。若是正常狀況下,你的寫請求量就會常常暴長到正常的幾倍,那麼你應該調大這個倍數並調整其餘參數值,好比hfile.block.cache.size和hbase.regionserver.global.memstore.upperLimit/lowerLimit,以預留更多內存,防止HBase server OOM。

(9)hbase.regionserver.global.memstore.upperLimit:默認40%

當ReigonServer內全部region的memstores所佔用內存總和達到heap的40%時,HBase會強制block全部的更新並flush這些region以釋放全部memstore佔用的內存。

hbase.regionserver.global.memstore.lowerLimit:默認35%

同upperLimit,只不過lowerLimit在全部region的memstores所佔用內存達到Heap的35%時,不flush全部的memstore。它會找一個memstore內存佔用最大的region,作個別flush,此時寫更新仍是會被block。lowerLimit算是一個在全部region強制flush致使性能下降前的補救措施。在日誌中,表現爲 「** Flushthread woke up with memory above low water.」。

調優:這是一個Heap內存保護參數,默認值已經能適用大多數場景。

(10)hfile.block.cache.size:默認20%

  這是涉及hbase讀取文件的主要配置,BlockCache主要提供給讀使用。讀請求先到memstore中查數據,查不到就到blockcache中查,再查不到就會到磁盤上讀,並把讀的結果放入blockcache。因爲blockcache是一個LRU,所以blockcache達到上限(heapsize * hfile.block.cache.size)後,會啓動淘汰機制,淘汰掉最老的一批數據。對於注重讀響應時間的系統,應該將blockcache設大些,好比設置blockcache=0.4,memstore=0.39,這會加大緩存命中率。

(11)hbase.regionserver.hlog.blocksize和hbase.regionserver.maxlogs

之因此把這兩個值放在一塊兒,是由於WAL的最大值由hbase.regionserver.maxlogs*hbase.regionserver.hlog.blocksize (2GB by default)決定。一旦達到這個值,Memstore flush就會被觸發。因此,當你增長Memstore的大小以及調整其餘的Memstore的設置項時,你也須要去調整HLog的配置項。不然,WAL的大小限制可能會首先被觸發,於是,你將利用不到其餘專門爲Memstore而設計的優化。拋開這些不說,經過WAL限制來觸發Memstore的flush並不是最佳方式,這樣作可能會會一次flush不少Region,儘管「寫數據」是很好的分佈於整個集羣,進而頗有可能會引起flush「大風暴」。

提示:最好將hbase.regionserver.hlog.blocksize* hbase.regionserver.maxlogs 設置爲稍微大於hbase.regionserver.global.memstore.lowerLimit* HBASE_HEAPSIZE。

6.HDFS優化部分

HBase是基於hdfs文件系統的一個數據庫,其數據最終是寫到hdfs中的,所以涉及hdfs調優的部分也是必不可少的。

(1)dfs.replication.interval:默認3秒

能夠調高,避免hdfs頻繁備份,從而提升吞吐率。

(2)dfs.datanode.handler.count:默認爲10

能夠調高這個處理線程數,使得寫數據更快

(3)dfs.namenode.handler.count:默認爲8

(4)dfs.datanode.socket.write.timeout:默認480秒,併發寫數據量大的時候能夠調高一些,不然會出現我另一篇博客介紹的的錯誤。

(5)dfs.socket.timeout:最好也要調高,默認的很小。

同上,能夠調高,提升總體速度與性能。

相關文章
相關標籤/搜索