Hbase 性能優化

1. 垃圾回收優化

用戶可以通過向hbase-env.sh文件中添加HBASE_OPTS或者HBASE_REGIONSERVER_OPT來設置垃圾回收相關選項,後者僅僅影響region服務器進程,也是推薦的修改方式。

增加新生代大小, 減小新生代垃圾回收次數

-XX:MaxNewSize=8g -XX:NewSize=8g

修改垃圾回收策略

-XX:+UseParNewGC

設置年輕代使用Parallel New Collector策略,這將停止運行Java進程而去清空年輕代堆。與老年代相比年輕代很小,所以這個過程話費時間很短,通常幾百毫秒。

-XX:+UseConcMarkSweepGC

以上策略如果用於年老代會造成region server幾秒鐘甚至數分鐘停頓,如果停頓時間超過zookeeper會話超時限制,這個服務器會被master認為已經崩潰,並且隨後會被拋棄。

這種情況可以使用並行標記回收策略(Concurrent Mark-Sweep Collector, CMS)來緩解, 不同之處在於其工作時試圖在不停止運行Java進程的情況下異步並行的完成工作。這種策略將增加CPU的負擔,但是卻可以避免重寫老生代碎片時的停頓--除非發生提示失敗,這種失敗會迫使垃圾回收暫停運行Java進程並進行內存整理。

2. 本地memstore分配緩衝區

由於memstore不斷創建和釋放內存空間, 就會在年老代Heap上產生孔洞。申請新空間時,由於碎片過多導致沒有足夠大的連續空間分配,JRE會退回到使用(stop the world)垃圾回收器,這樣會導致其重寫整個堆空間並壓縮剩餘的可用對象。

MSLAB(memstore-local allocation buffers)是許多固定大小的緩衝區,用來存儲大小不同的keyvalue實例。當一個緩衝區不能放下一個新加入的keyvalue時,系統就認為這個緩衝區已經佔滿了,然後創建一個新的固定大小的緩衝區。 一旦這些緩衝區對象被回收,他們將在堆中留下固定大小的孔洞,之後調用固定大小的新對象將會重新使用這些孔洞,這樣就不需要JRE停止壓縮回收堆內存了。

但是mslab也有一些副作用,比如更加浪費堆空間;使用緩衝區需要額外的內存複製工作,比直接使用keyvalue實例要稍微慢一點

配置hbase-site.xml中的 hbase.hregion.memstore.mslab.enabled 默認值 true

3 壓縮

除非存儲已經壓縮過的內容如JPEG圖像,對於其它場景來說,壓縮通常會帶來較好的性能,因為CPU壓縮和解壓的時間比從磁盤讀取和寫入更多數據消耗的時間更短。

算法壓縮比 %壓縮 MB/S解壓 MB/SGZIP13.421118LZO20.5135410Zippy/Snappy22.2172409

默認Hbase對文件是沒有壓縮的, 查看 describe 'tablename'

4. 優化拆分和合並

通常Hbase是自動處理Region拆分的,一旦它們到了預定的閾值,region將被拆分成兩個,之後它們可以接受新的數據並繼續增長。 當用戶的region大小已恆定速度增長時,region拆分會在同一時間發生,因為同時需要壓縮region中的存儲文件,這個過程會重寫拆分之後的數據,這將引起IO上升,稱之為“拆分和並風暴”。

與其依賴自動拆分,不如關閉這個行為調用split和major_compace命令手動拆分。

為防止自動拆分可設置hbase.hregion.max.filesize的值為一個比較大的值,比如100GB。 然後用客戶端實現一個調用split()和 majorCompact()的客戶端,也可以使用shell交互的調用相關命令,或者使用cron定時的調用它們。

另一種方法是創建表時進行預拆分

create 't1', 'f1', SPLITS => ['10', '20', '30', '40']

5.負載均衡

master內置了一個叫做均衡器的特性,默認情況下每5分鐘(通過hbase.balancer.period設置)運行一次。 一旦均衡器啟動,它會嘗試均勻分配region到所有region服務器。用戶可通過shell的balance_switch命令來更改均衡器的開啟或關閉狀態。

除了依賴均衡器自動完成工作,用戶還可以使用move命令顯示地將region移動到另一個region server上。

6. 合併region

當用戶刪除大量數據並且想減少每個服務器管理的region數量,可以使用merge_region命令合併相鄰的region。

7 客戶端API最佳實踐

禁止自動刷新

put.setAutoFlush(false)

使用掃描緩存

scan.setCaching(1000);

限定掃描範圍

儘量只在一個Family中掃描

關閉ResultScanner

一定要在try catch 的 finally 中關閉ResultScanner

快緩存用法

scan.setCacheBlocks() 對於那些頻繁訪問的行,建議使用塊緩存

優化獲取行健的方式當用戶僅需要獲取需要的行健時,在Scan中用setFilter()方法添加一個帶MUST_PASS_ALL的FilterList。FilterList中包含FirstKeyFilter和KeyOnlyFilter兩個過濾器。使用以上的組合過濾器將會把發現的第一個keyvalue行健返回給客戶端。

關閉put上的WAL

當需要存入的數據對準確度要求不是很高時,使用Put的writeToWAL(false)來關閉WAL。

Hbase 性能優化


分享到:


相關文章: