hbase優化操作與建議
一、服務端調優
1、參數配置
1)、hbase.regionserver.handler.count:該設置決定了處理RPC的線程數量,默認值是10,通常可以調大,比如:150,當請求內容很大(上MB,比如大的put、使用緩存的scans)的時候,如果該值設置過大則會占用過多的內存,導致頻繁的GC,或者出現OutOfMemory,因此該值不是越大越好。
2)、hbase.hregion.max.filesize :配置region大小,0.94.12版本默認是10G,region的大小與集群支持的總數據量有關系,如果總數據量小,則單個region太大,不利於並行的數據處理,如果集群需支持的總數據量比較大,region太小,則會導致region的個數過多,導致region的管理等成本過高,如果一個RS配置的磁盤總量為3T*12=36T數據量,數據復制3份,則一臺RS服務器可以存儲10T的數據,如果每個region最大為10G,則最多1000個region,如此看,94.12的這個默認配置還是比較合適的,不過如果要自己管理split,則應該調大該值,並且在建表時規劃好region數量和rowkey設計,進行region預建,做到一定時間內,每個region的數據大小在一定的數據量之下,當發現有大的region,或者需要對整個表進行region擴充時再進行split操作,一般提供在線服務的hbase集群均會棄用hbase的自動split,轉而自己管理split。
3)、hbase.hregion.majorcompaction:配置major合並的間隔時間,默認為1天,可設置為0,禁止自動的major合並,可手動或者通過腳本定期進行major合並,有兩種compact:minor和major,minor通常會把數個小的相鄰的storeFile合並成一個大的storeFile,minor不會刪除標示為刪除的數據和過期的數據,major會刪除需刪除的數據,major合並之後,一個store只有一個storeFile文件,會對store的所有數據進行重寫,有較大的性能消耗。
4)、hbase.hstore.compactionThreshold:HStore的storeFile數量>= compactionThreshold配置的值,則可能會進行compact,默認值為3,可以調大,比如設置為6,在定期的major compact中進行剩下文件的合並。
5)、 hbase.hstore.blockingStoreFiles:HStore的storeFile的文件數大於配置值,則在flush memstore前先進行split或者compact,除非超過hbase.hstore.blockingWaitTime配置的時間,默認為7,可調大,比如:100,避免memstore不及時flush,當寫入量大時,觸發memstore的block,從而阻塞寫操作。
6)、hbase.regionserver.global.memstore.upperLimit:默認值0.4,RS所有memstore占用內存在總內存中的upper比例,當達到該值,則會從整個RS中找出最需要flush的region進行flush,直到總內存比例降至該數限制以下,並且在降至限制比例以下前將阻塞所有的寫memstore的操作,在以寫為主的集群中,可以調大該配置項,不建議太大,因為block cache和memstore cache的總大小不會超過0.8,而且不建議這兩個cache的大小總和達到或者接近0.8,避免OOM,在偏向寫的業務時,可配置為0.45,memstore.lowerLimit保持0.35不變,在偏向讀的業務中,可調低為0.35,同時memstore.lowerLimit調低為0.3,或者再向下0.05個點,不能太低,除非只有很小的寫入操作,如果是兼顧讀寫,則采用默認值即可。
7)、hbase.regionserver.global.memstore.lowerLimit:默認值0.35,RS的所有memstore占用內存在總內存中的lower比例,當達到該值,則會從整個RS中找出最需要flush的region進行flush,配置時需結合memstore.upperLimit和block cache的配置。
8)、file.block.cache.size:RS的block cache的內存大小限制,默認值0.25,在偏向讀的業務中,可以適當調大該值,具體配置時需試hbase集群服務的業務特征,結合memstore的內存占比進行綜合考慮。
9)、hbase.hregion.memstore.flush.size:默認值128M,單位字節,超過將被flush到hdfs,該值比較適中,一般不需要調整。
10)、hbase.hregion.memstore.block.multiplier:默認值2,如果memstore的內存大小已經超過了hbase.hregion.memstore.flush.size的2倍,則會阻塞memstore的寫操作,直到降至該值以下,為避免發生阻塞,最好調大該值,比如:4,不可太大,如果太大,則會增大導致整個RS的memstore內存超過memstore.upperLimit限制的可能性,進而增大阻塞整個RS的寫的幾率。如果region發生了阻塞會導致大量的線程被阻塞在到該region上,從而其它region的線程數會下降,影響整體的RS服務能力,例如:
開始阻塞:
解開阻塞:
從10分11秒開始阻塞到10分20秒解開,總耗時9秒,在這9秒中無法寫入,並且這期間可能會占用大量的RS handler線程,用於其它region或者操作的線程數會逐漸減少,從而影響到整體的性能,也可以通過異步寫,並限制寫的速度,避免出現阻塞。
11)、hfile.block.index.cacheonwrite:在index寫入的時候允許put無根(non-root)的多級索引塊到block cache裏,默認是false,設置為true,或許讀性能更好,但是是否有副作用還需調查。
12)、io.storefile.bloom.cacheonwrite:默認為false,需調查其作用。
13)、hbase.regionserver.regionSplitLimit:控制最大的region數量,超過則不可以進行split操作,默認是Integer.MAX,可設置為1,禁止自動的split,通過人工,或者寫腳本在集群空閑時執行。如果不禁止自動的split,則當region大小超過hbase.hregion.max.filesize時會觸發split操作(具體的split有一定的策略,不僅僅通過該參數控制,前期的split會考慮region數據量和memstore大小),每次flush或者compact之後,regionserver都會檢查是否需要Split,split會先下線老region再上線split後的region,該過程會很快,但是會存在兩個問題:1、老region下線後,新region上線前client訪問會失敗,在重試過程中會成功但是如果是提供實時服務的系統則響應時長會增加;2、split後的compact是一個比較耗資源的動作。
14)、Jvm調整
a、內存大小:master默認為1G,可增加到2G,regionserver默認1G,可調大到10G,或者更大,zk並不耗資源,可以不用調整;
b、垃圾回收:待研究。
2、其它調優
1)、列族、rowkey要盡量短,每個cell值均會存儲一次列族名稱和rowkey,甚至列名稱也要盡量短,以下截圖是表test2的數據和存入hdfs後的文件內容:
由上圖可見:短的列族名稱、rowkey、列名稱對最終的文件內容大小影響很大。
2)、RS的region數量:一般每個RegionServer不要過1000,過多的region會導致產生較多的小文件,從而導致更多的compact,當有大量的超過5G的region並且RS總region數達到1000時,應該考慮擴容。
3)、建表時:
a、如果不需要多版本,則應設置version=1;
b、開啟lzo或者snappy壓縮,壓縮會消耗一定的CPU,但是,磁盤IO和網絡IO將獲得極大的改善,大致可以壓縮4~5倍;
c、合理的設計rowkey,在設計rowkey時需充分的理解現有業務並合理預見未來業務,不合理的rowkey設計將導致極差的hbase操作性能;
d、合理的規劃數據量,進行預分區,避免在表使用過程中的不斷split,並把數據的讀寫分散到不同的RS,充分的發揮集群的作用;
e、列族名稱盡量短,比如:“f”,並且盡量只有一個列族;
f、視場景開啟bloomfilter,優化讀性能。
二、Client端調優
1、hbase.client.write.buffer:寫緩存大小,默認為2M,推薦設置為6M,單位是字節,當然不是越大越好,如果太大,則占用的內存太多;
2、hbase.client.scanner.caching:scan緩存,默認為1,太小,可根據具體的業務特征進行配置,原則上不可太大,避免占用過多的client和rs的內存,一般最大幾百,如果一條數據太大,則應該設置一個較小的值,通常是設置業務需求的一次查詢的數據條數,比如:業務特點決定了一次最多100條,則可以設置為100
3、設置合理的超時時間和重試次數,具體的內容會在後續的blog中詳細講解。
4、client應用讀寫分離
讀和寫分離,位於不同的tomcat實例,數據先寫入redis隊列,再異步寫入hbase,如果寫失敗再回存redis隊列,先讀redis緩存的數據(如果有緩存,需要註意這裏的redis緩存不是redis隊列),如果沒有讀到再讀hbase。
當hbase集群不可用,或者某個RS不可用時,因為HBase的重試次數和超時時間均比較大(為保證正常的業務訪問,不可能調整到比較小的值,如果一個RS掛了,一次讀或者寫,經過若幹重試和超時可能會持續幾十秒,或者幾分鐘),所以一次操作可能會持續很長時間,導致tomcat線程被一個請求長時間占用,tomcat的線程數有限,會被快速占完,導致沒有空余線程做其它操作,讀寫分離後,寫由於采用先寫redis隊列,再異步寫hbase,因此不會出現tomcat線程被占滿的問題, 應用還可以提供寫服務,如果是充值等業務,則不會損失收入,並且讀服務出現tomcat線程被占滿的時間也會變長一些,如果運維介入及時,則讀服務影響也比較有限。
5、如果把org.apache.hadoop.hbase.client.HBaseAdmin配置為spring的bean,則需配置為懶加載,避免在啟動時鏈接hbase的Master失敗導致啟動失敗,從而無法進行一些降級操作。
6、Scan查詢編程優化:
1)、調整caching;
2)、如果是類似全表掃描這種查詢,或者定期的任務,則可以設置scan的setCacheBlocks為false,避免無用緩存;
3)、關閉scanner,避免浪費客戶端和服務器的內存;
4)、限定掃描範圍:指定列簇或者指定要查詢的列;
5)、如果只查詢rowkey時,則使用KeyOnlyFilter可大量減少網絡消耗;
作為hbase依賴的狀態協調者ZK和數據的存儲則HDFS,也需要調優:
ZK調優:
1、zookeeper.session.timeout:默認值3分鐘,不可配置太短,避免session超時,hbase停止服務,線上生產環境由於配置為1分鐘,出現過2次該原因導致的hbase停止服務,也不可配置太長,如果太長,當rs掛掉,zk不能快速知道,從而導致master不能及時對region進行遷移。
2、zookeeper數量:至少5個節點。給每個zookeeper 1G左右的內存,最好有獨立的磁盤。 (獨立磁盤可以確保zookeeper不受影響).如果集群負載很重,不要把Zookeeper和RegionServer運行在同一臺機器上面。就像DataNodes 和 TaskTrackers一樣,只有超過半數的zk存在才會提供服務,比如:共5臺,則最多只運行掛2臺,配置4臺與3臺一樣,最多只運行掛1臺。
3、hbase.zookeeper.property.maxClientCnxns:zk的最大連接數,默認為300,可配置上千
hdfs調優:
1、dfs.name.dir: namenode的數據存放地址,可以配置多個,位於不同的磁盤並配置一個NFS遠程文件系統,這樣nn的數據可以有多個備份
2、dfs.data.dir:dn數據存放地址,每個磁盤配置一個路徑,這樣可以大大提高並行讀寫的能力
3、dfs.namenode.handler.count:nn節點RPC的處理線程數,默認為10,需提高,比如:60
4、dfs.datanode.handler.count:dn節點RPC的處理線程數,默認為3,需提高,比如:20
5、dfs.datanode.max.xcievers:dn同時處理文件的上限,默認為256,需提高,比如:8192
6、dfs.block.size:dn數據塊的大小,默認為64M,如果存儲的文件均是比較大的文件則可以考慮調大,比如,在使用hbase時,可以設置為128M,註意單位是字節
7、dfs.balance.bandwidthPerSec:在通過start-balancer.sh做負載均衡時控制傳輸文件的速度,默認為1M/s,可配置為幾十M/s,比如:20M/s
8、dfs.datanode.du.reserved:每塊磁盤保留的空余空間,應預留一些給非hdfs文件使用,默認值為0
9、dfs.datanode.failed.volumes.tolerated:在啟動時會導致dn掛掉的壞磁盤數量,默認為0,即有一個磁盤壞了,就掛掉dn,可以不調整。
本文檔轉載自 HBase性能調優
hbase優化操作與建議