目錄:java
1,背景node
2,GCmysql
3,hbase cachesql
4,compactionshell
5,其餘數據庫
1,背景緩存
項目組中,hbase主要用來備份mysql數據庫中的表。主要經過接入mysql binlog,經storm存儲到hbase。因爲是實時接入binlog寫入,寫的壓力不是很大,主要是晚上離線計算的時候,須要將hbase中的表同步到HDFS中,這個時候對hbase的讀性能以及全表掃描性能要求有些高,以儘可能較少數據導入時間。因爲以前時間倉促,以及對hbase瞭解有限等緣由,hbase這塊問題多多。當前階段比較突出的問題主要有兩個方面:第一,full GC頻繁。 第二,儘可能提高hbase的讀性能,尤爲是scan的性能。併發
2,GC運維
問題:經過jstat命令發現regionserver進程full GC很是的頻繁,甚至發現full GC的次數比young gc的次數還要多。full gc嚴重致使region server不穩定,常常運行幾天後regionserver會死掉。性能
緣由:經過分析gc log以及實時觀察,發現主要是讀頻發的時候,young區的S1,S2會很快到達100%,致使新的對象快速進入old區,此外,old區full gc不能有效快速回收內存,致使old去的內存一直維持在高位(老是高於設定的CMSInitiatingOccupancyFraction),因此致使old gc比young gc還多。
嘗試辦法:因爲young區在hbase讀頻繁的時候很快被填滿,因此很天然的嘗試即是增大young區的大小。可是大了之後產生了兩個負面效果,一是young gc時間變長了,二是仍是不能解決read的時候young區被快速填滿的問題。這時意識到,單純經過GC調參來解決full gc頻繁問題的思路行不通了。
mark一下優化後的GC配置:
export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS $HBASE_JMX_BASE -Xmx2000m -Xms2000m -Xmn750m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:-CMSIncrementalMode -XX:CMSInitiatingOccupancyFraction=70"
export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS $HBASE_JMX_BASE -Xmx16000m -Xms16000m -Xmn7000m -XX:MaxDirectMemorySize=5g -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:-CMSIncrementalMode -XX:CMSInitiatingOccupancyFraction=75 -Xloggc:${HOME}/hdp_data/hbase/rs.log-`date +'%Y%m%d%H%M'` -verbose:gc -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:SurvivorRatio=2 -XX:+PrintTenuringDistribution"
3,hbase cache
hbase中與內存相關的主要是memstore和block cache,memstore主要服務於寫,而block cache主要服務與讀。有關block cache的詳細介紹,能夠參看block cache。hbase默認的block cache策略是LRU block cache,這時全部的cache都放在java進程的heap中,因此致使對hbase讀的時候heap中的內存快速增加。bucket cache經過將date block緩存到direct buffer管理的堆外內存中,有效解決了這個問題。一般採用一種混合的策略即combined block cache(LRU block cache + bucket cache). LRU block cache主要用來緩存bloom過濾器,索引等。配置以下:
GC參數設置:-XX:MaxDirectMemorySize=5g,設置java進程使用direct memory的最大值。
hbase-site.xml中配置以下:
<!--LRU Cache--> <property> <name>hfile.block.cache.size</name> <value>0.4</value> </property> <!--Bucket cache--> <property> <name>hbase.bucketcache.ioengine</name> <value>offheap</value> </property> <property> <name>hbase.bucketcache.size</name> <value>4196</value> </property>
設置之後,hbase regionsever進程full gc問題圓滿解決。
4,hbase compaction
hbase compaction主要是合併memstore flush到磁盤上的HFile文件。主要分minor compaction和major compaction。minor compaction只會合併不多的hfile,這個花費的時間也不是很長。而major compaction會合並指定table的全部的HFile,因此花費的時間也比較長,可是可以顯著提升hbase的讀性能。考慮到白天hbase集羣的負載並非很高,因此很天然想到就是作手工major compaction。寫一個簡單的腳本就行了。其實就一行語句:echo "major_compact 'tablename'" | hbase shell,而後經過crontab定時啓動就行了。作了major compaction之後region server的block locality明顯好轉,hbase讀的性能提高提高了50%以上,晚上導表時間幾乎縮短了一半。
5,其餘
其餘的方法也嘗試了一些,比方說設置hbase.client.scanner.caching參數,以及在每臺datenode的機器上都部署region sever以加強data locality,還有增大hbase導表的併發數等,這些有一些效果,可是不是太明顯。
總的來講,此次主要是熟悉hbase相關的原理和配置,而後經過設置一些策略和參數來提高hbase的性能,雖然比較簡單粗暴,可是以上方法已基本知足當前需求,因此對hbase讀性能的優化暫時告一段落。接下來會對hbase的穩定性以及可運維性作一些測試。