1.垃圾回收器調優
當咱們往hbase寫入數據,它首先寫入memstore當中,當menstore的值大於hbase.hregion.memstore.flush.size參數中設置的值後,就會寫入硬盤。shell
在hbase-env.sh文件中,咱們能夠設置HBASE_OPTS或者HBASE_REGIONSERVER_OPTS,後者隻影響region server進程。數組
export HBASE_REGIONSERVER_OPTS="-Xmx8g -Xms8g -Xmn128m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:$HBASE_HOME/logs/gc-$(hostname)-hbase.log"app
《hbase權威指南》推薦了上述的寫法,下面是從網上搜的,原書中爲何要這麼設置的解釋真心看不懂。負載均衡
-Xmx8g -Xms8g –Xmn128m :最大堆內存8G,最小堆內存8G,新生代內存-Xmn128m。性能
-XX:+UseParNewGC : 設置對於新生代的垃圾回收器類型,這種類型是會中止JAVA進程,而後再進行回收的,但因爲新生代體積比較小,持續時間一般只有幾毫秒,所以能夠接受。優化
-XX:+UseConcMarkSweepGC :設置老生代的垃圾回收類型,若是用新生代的那個會不合適,即會致使JAVA進程中止的時間太長,用這種不會中止JAVA進程,而是在JAVA進程運行的同時,並行的進行回收。spa
-XX:CMSInitiatingOccupancyFraction :設置CMS回收器運行的頻率,避免前兩個參數引發JAVA進程長時間中止,設置了這個以後,不須要中止JAVA進程,可是會提升CPU使用率。設計
最後兩句是輸出詳細的日誌。日誌
2.MemStore-Local Allocation Buffer
MemStore-Local Allocation Buffer,是Cloudera在HBase 0.90.1時提交的一個patch裏包含的特性。它基於Arena Allocation解決了HBase因Region flush致使的內存碎片問題。orm
MSLAB的實現原理(對照Arena Allocation,HBase實現細節):
MemstoreLAB爲Memstore提供Allocator。
建立一個2M(默認)的Chunk數組和一個chunk偏移量,默認值爲0。
當Memstore有新的KeyValue被插入時,經過KeyValue.getBuffer()取得data bytes數組。將data複製到Chunk數組起始位置爲chunk偏移量處,並增長偏移量=偏移量+data.length。
當一個chunk滿了之後,再建立一個chunk。
全部操做lock free,基於CMS原語。
優點:
KeyValue原始數據在minor gc時被銷燬。
數據存放在2m大小的chunk中,chunk歸屬於memstore。
flush時,只須要釋放多個2m的chunks,chunk未滿也強制釋放,從而爲Heap騰出了多個2M大小的內存區間,減小碎片密集程度。
開啓MSLAB
hbase.hregion.memstore.mslab.enabled=true // 開啓MSALB
hbase.hregion.memstore.mslab.chunksize=2m // chunk的大小,越大內存連續性越好,但內存平均利用率會下降,要比插入的單元格的數據大一些。
hbase.hregion.memstore.mslab.max.allocation=256K // 經過MSLAB分配的對象不能超過256K,不然直接在Heap上分配,256K夠大了。
3.壓縮存儲
直接上圖吧,說多了沒用。
推薦使用Snappy,性能最好,可是Snappy要單獨安裝,安裝教程等我裝成功了,再發一個文檔出來吧。
4.優化Splits and Compactions
對於實時性要求穩定的系統來講,不定時的split和compact會使集羣的響應時間出現比較大的波動,所以建議把split和compact關閉,手動進行操做,好比咱們把hbase.hregion.max.filesize設置成100G(major compaction大概須要一小時,設置太大了,compaction會須要更多的時間),major compaction是必需要作的,羣裏有個網友給數據設置了過時時間,數據被邏輯刪除了,可是沒有釋放硬盤空間,why?沒有進行major compaction,最後是手動進行的合併。
5.平衡分佈
在咱們設計rowkey的時候,在前面加上隨機數,好比0rowkey-1,1rowkey-2,0rowkey-3,1rowkey-4,去前面加上個隨機數,就會有負載均衡的效果,可是若是這樣作了,某個機器的數據仍是比別的機器要多不少,這個怎麼辦呢?咱們能夠手動調用move()方法,經過shell或者HBaseAdmin類,或者調用unassign()方法,數據就會轉移了。