1. 程式人生 > >hbase調優總結

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,可配置上千

 

hdf調優:

  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,可以不調整。