Hbase性能調優(二)


 

一、HBase關鍵參數配置指導

如果同時存在讀和寫的操作,這兩種操作的性能會相互影響。如果寫入導致的flush和Compaction操作頻繁發生,會占用大量的磁盤IO操作,從而影響讀取的性能。如果寫入導致阻塞較多的Compaction操作,就會出現Region中存在多個HFile的情況,從而影響讀取的性能。所以如果讀取的性能不理想的時候,也要考慮寫入的配置是否合理。

1、提升寫效率

1.1客戶端調優

1.1.1 AutoFlush

參數值:setAutoFlush

解析:

  autoflush=false的原理是當客戶端提交delete或put請求時,將該請求在客戶端緩存,直到數據超過2M(hbase.client.write.buffer決定)或用戶執行了hbase.flushcommits()時才向regionserver提交請求。因此即使htable.pu()執行返回成功,也並非說明請求真的成功了。假如還沒有達到該緩存而client崩潰,該部分數據將由於未發送到regionserver而丟失。這對於零容忍的在線服務是不可接受的。

  autoflush=true雖然會讓寫入速度下降2-3本,但是對於很多在線應用來說這都是必須打開的,也正是hbase為什么讓它默認為true的原因,每次請求都會發往regionserver,而regionserver接收到請求后第一件事情就是寫HLOG。因此對IO要求是非常高的,為了提高hbase的寫入速度應該盡可能地提高IO吞吐量,比如增加磁盤、使用raid卡、減少replication因子數等。

如何調優?

  經驗設定:

  setAutoFlush=false

1.1.2使用PutList方式提交請求

  可以極大地提升寫性能

1.2  Memstore相關

  當regionserver(以下簡稱為RS)收到一個寫請求,會將這個請求定位到某個特定的region。每一個region存儲了一系列的Row,每一個Row對應的數據分散在一個或多個ColumnFamily(以下簡稱為CF)。特定CF的數據都存儲在對應的store里面,而每個store都是由一個memstore和數個storefile組成。memstore存儲在RS的內存中,而storefile則存儲在HDFS上。當一個寫請求到達RS的時候,該請求對應的數據首先會被menstore存儲,直到達到一定的臨界條件,memstore里面的數據才會flush到storefile。

  使用memstore的主要原因是為了使存儲在HDFS上的數據是有序的(按Row)。HDFS設計為順序讀寫的,已有的文件不能被修改。這就意味着,因為hbase收到的寫請求是無序的,所以如果直接將這些數據寫到HDFS上,以后再對文件里面的內二做排序就會是一件極其困難的事情;無序的數據存儲方式,又會大大影響后續的讀請求性能。為了解決這種問題,hbase會將最近的某些寫請求放到內存中(也就是memstore),並將這些數據在flush到storefile之前做好排序。

  除了解決排序的問題,memstore還有其他好處,比如:

  它能充當memcache的角色,緩存最近寫入的數據。鑒於新數據的訪問頻率和幾率都比舊數據高很多,這就大大的提高客戶端的讀效率。

  注意:每個memstore每次刷新時,都會給CF生產一個storefile。

  剩下讀取就非常容易了,hbase會檢查數據是否在memstore里面,否則就去storefile讀取,然后返回給客戶端。

 

1.2.1 根據memstore大小flush hfile

  參數值:hbase.hregion.memstore.flush.size

  參數解析:

    在regionserver中,當寫操作內存中存在超過memstore.flush.size大小的memstore,則MemstoreFlusher就啟動flush操作將該memstore以hfile的形式寫入對應的store中。

  如何調優?

  默認:128M

  A、如果Regionserver的內存充足,而且活躍Region數量也不是很多的時候,可以適當增大該值,可以減少compaction的次數,有助於提升系統性能。

  B、這種flush產生的時候,並不是緊急的flush,flush操作可能會有一定延遲,在延遲期間,寫操作還可以進行,Memstore還會繼續增大,最大值 = “memstore.flush.size” * "hbase.hregion.memstore.block.multiplier"。

  C、當超過最大值時,將會阻塞寫操作。適當增大“hbase.hregion.memstore.block.multiplier”可以減少阻塞,減少性能波動。

 

  參數值:hbase.regionserver.global.memstore.size

  參數解析:

    RegionServer中,負責flush操作的是MemStoreFlusher線程。該線程定期檢查寫操作內存,當寫操作占用內存總量達到閾值,MemStoreFlusher將啟動flush操作,按照從大到小的順序,flush若干相對較大的memstore,直到所占用內存小於閾值。

    閾值=“hbase.regionserver.global.memstore.size” * "hbase.regionserver.global.memstore,size.lower.limit" * "Hbase_HEAPSIZE"

  如何調優?

    默認:0.4

    該配置與“hfile.block.cache.size”的和不能超過0.8,也就是寫和讀操作的內存不能超過HeapSize的80%,這樣可以保證除讀和寫以外其他操作的正常運行。

 

1.2.3  Flush前進行Compaction

  參數值:hbase.hstore.blockingStoreFiles

  參數解析:

    在region flush前首先判斷file文件個數,是否大於hbase.hstore.blockingStoreFiles。如果大於需要先Compaction並且讓flush延時90s(這個參數可以通過hbase.hstore.blockingWaitTime進行配置),在延時過程中,將會繼續寫從而使得Memstore還會繼續增大超過閾值(“memstore.flush.size” * "hbase.hregion.memstore.block.multiplier"),導致寫操作阻塞。當完成Compaction后,可能就會產生大量寫入。這樣就導致性能激烈震盪。

  如何調優?

    默認:7

    增加hbase.hstore.blockingStoreFiles,可以降低Block幾率。

1.3 內存相關

  Hbase利用內存完成讀寫操作。提高Hbase內存可以有效提高Hbase性能。

1.3.1 GC參數

  參數值:GC_OPTS

  參數解析:

    GC_OPTS主要需要調整HeapSize的大小和NewSize的大小。

    HMaster:

      - -Xms512M -Xmx1G -XX:NewSize=64M -XX:MaxNewSize=128M
    RegionServer
      - -Xms4G -Xmx6G -XX:NewSize=64M -XX:MaxNewSize=128M
  如何調優?

    A、挑戰者HeapSize大小的時候,建議將Xms和Xmx設置成相同的值,這樣可以避免JVM動態調整HeapSize大小的時候影響性能。

    B、調整NewSize大小的時候,建議把其設置為HeapSize大小的1/9

    C、HMaster:當HBase集群規模越大、Region數量越多時,可以適當調大HMaster的GC_OPTS參數。

    D、RegionServer:RegionServer需要的內存一般比HMaster要大。在內存充足的情況下,HeapSize可以相對設置大一些。

  經驗設定:

    主Hmaster的HeapSize為4G的時候,Hbase集群可以支持100000Region數的規模。根據經驗值,單個RegionServer的HeapSize不建議超過20G。

 

1.4 HFile相關

1.4.1文件同步sync

參數值:hbase.regionserver.hfile.durable.sync

參數解析:

  控制HFfile文件在寫入到HDFS時的同步程度。如果為true,HDFS在把數據寫入到硬盤后才返回:如果為false,HDFS在把數據寫入OS的緩存后就返回。

如何調優?

  默認為true

  把該值設置為false比設為true時在寫入性能上會更優。

1.5 Compaction相關

  1.5.1Compact文件大小閾值

  參數值:hbase.regionserver.thread.compaction.throttle

  參數解析:

    控制一次Minor Compaction時,進行compaction的文件總大小的閾值。

  如何調優?

    默認:1.5G

    Compaction時的文件總大小會影響這一次compaction的執行時間,如果太大,可能會阻塞其他的compaction或flush操作。

  

  1.5.2 Compact文件個數閾值

  參數值:hbase.hstore.compaction.min

  參數解析:

    當一個Store中文件超過該值時,會進行compact。

  如何調優?

    默認:3

    適當增大該值,可以減少文件被重復執行compaction,但是如果過大,會導致Store中文件數過多而影響讀取的性能。

  

  1.5.3 Compact文件數目

  參數值:hbase.hstore.compaction.max

  參數解析:

    控制一次compaction操作時的文件數量的最大值。

  如何調優?

    默認:10

    與“hbase.hstore.compaction.max.size”的作用基本相同,主要是控制一次compaction操作的時間不要太長。

  

  1.5.4 Compact文件大小選擇

  參數值:hbase.hstore.compaction.max.size

  參數解析:

    如果一個HFle文件的大小大於該值,那么Minor Compaction操作中不會選擇這個文件進行compaction操作,除非進行Major Compaction操作。

  如何調優?

    默認:2.5G

    這個值可以防止較大的HFile參與Compaction操作。在禁止Major Compaction后,一個Store中可能存在幾個HFile,而不會合並成一個HFile,這樣不會對數據讀取造成太大的性能影響。

 

  1.5.5 Major Compaction執行周期

  參數值:hbase.hregion.majorcompaction
  參數解析:由
於執行 Major Compaction 會占用較多的系統資源,如果正在處於系統繁忙時期,會影響系統的性能 。

  如何調優?

    默認: 24 小時    

    A. 如果業務沒有較多的更新、刪除、回收過期數據空間時, 建議設置為 0,以禁止Major Compaction

    B. 如果必須要執行 Major Compaction,以回收更多的空間,可以適當增加該值,同時配置參數“hbase.offpeak.end.hour”“hbase.offpeak.start.hour”以控制 Major Compaction 發生在業務空閑的時期。

1.6 HLog相關

  RS 上有一個 Write-ahead Log (以下簡稱 WAL),數據會持續的默認寫到這個文件中。它包含了所有已經提交到 RS 的,已經保留在 memstore 中但是尚未 flush storefile 的數據編輯歷史。

這些在 memstore 中的,尚未持久化的數據,在 RS 發生錯誤時我們需要借助它進行恢復,它能重現這些尚未持久化的數據的編輯軌跡。 .

WAL(Hlog)變得非常大時,重現它的記錄會花費非常多的時間。因此,我們需要限制WAL 的大小,當達到這個大小時,會觸發 memstore flush

當數據 flush 到磁盤后,WAL 的大小就會變小,因為我們不需要再保存這些已經完成持久化的數據編輯記錄。 

  1.6.1 文件同步sync

  參數值:hbase.regionserver.wal.durable.sync 

  參數解析:

    控制 HLog 文件在寫入到 HDFS 時的同步程度。如果為 trueHDFS 在把數據寫入到硬盤后才返回;如果為 falseHDFS 在把數據寫入 OS 的緩存后就返回。 

  如何調優?

    把該值設置為 false true 在寫入性能上會更優。
 
  

  1.6.2 Hlog Flush條件

  參數值:hbase.regionserver.maxlogs             hbase.regionserver.hlog.blocksize
  參數解析:

    A、表示一個RegionServer上未進行Flush的Hlog的文件數量的閾值,如果大於該值,RegionServer會強制進行flush操作。

    B、表示每個Hlog文件的最大大小。如果Hlog文件大小大於該值,就會滾動出一個新的Hlog,舊的將被禁用並歸檔。

  如何調優?

    這兩個參數共同決定了RegionServer中可以存在的未進行Flush的hlog數量。WAL的最大容量 = hbase.regionserver.maxlogs * hbase.regionserver.hlog.blocksize。當達到這個容量的時候,memstore flush就會被觸發。因此,你在調整memstore的設置的時候,你同樣需要調整這些值來適應那些編號。否則,WAL容量達到限制可能導致memstore flush的罪魁禍首,你專門配置memstore參數所增加的資源可能永遠無法被物盡其用。這個時候可以適當調整這兩個參數的大小。以避免出現這種強制flush的情況。

   經驗設定:

    hbase.regionserver.maxlogs:默認32,建議調整為100

    hbase.regionserver.hlog.blocksize:默認64M,建議調整為128M

1.7 表設計相關

  1.7.1壓縮算法

  參數值:COMPRESSION

  參數解析:配置數據的壓縮算法,這里的壓縮是HFile中block級別的壓縮。對於可以壓縮的數據,配置壓縮算法可以有效減少磁盤的IO,從而達到提高性能的目的。

  如何優化?

    默認:None

    並非所有數據都可以進行有效的壓縮。例如一張圖片的數據,因為圖片一般已經是壓縮后的數據,所以壓縮效果有限。推薦使用SNAPPY,因為它有較好的Encoding / Decoding 速度和可以接受的壓縮率。

    實例:create 'test_table',{NAME => 'cf1', COMPRESSION => 'SNAPPY'}

  1.7.2 Block大小

  參數值:BLOCKSIZE

  參數解析:

    配置HFile中block塊的大小,不同的block塊大小,可以影響HBase讀寫數據的效率。越大的block塊,配合壓縮算法,壓縮的效率就越好;但是由於HBase的讀取數據是以block塊為單位的,所以越大的block塊,對應隨機讀的情況,性能可能會比較差。

  如何調優?

    默認:64Kb

    如果要提升寫入性能,一般擴大到128kb或者256kb,可以提升寫數據的效率,也不會影響太大的隨機讀性能。

    實例:create 'test_table',{NAME => 'cf1', BLOCKSIZE => '32768'}
  

  1.7.3 緩存內存

  參數值:IN_MEMORY

  參數解析:

    配置這個表的數據有限緩存在內存中,這樣可以有效提升讀取的性能。

  如何調優?

    默認:false

    對於一些小表,而且需要頻繁進行讀取操作的,可以設置此配置項

    實例:create 'test_table',{NAME => 'cf1', IN_MEMORY => 'true'}

 

2、提升讀效率

2.1 客戶端調優

A、Scan數據時需要設置caching(一次從服務端讀取的記錄條數,默認是1),若使用默認值讀性能會降到極低。

B、當不需要讀一條數據所有列時,需要指定讀取的列,以減少網絡IO

C、只讀取Rowkey時,可以為Scan添加一個只讀取Rowkey的filter(FirstKeyOnlyFilter或者KeyOnlyFilter)。

D、在客戶端代碼中,可以設置caching和batch用來提升查詢效率。

   例如:Scan.setCaching(caching);scan.setBatch(batch); caching batch 都為 1 的時候,我們要返回 10 行具有 20 列的記錄,就要進行 201 RPC, 因為每一列都作為一個單獨的 Result 來返回,這樣是我們不可以接受的(還有一次 RPC 是用來確認 scan 已經完成) 。

     a) RPC 次數公式: RPCs = (Rows * Cols per Row) / Min(Cols per Row, Batch Size)/Scanner Caching 

 

2.2 內存相關

Hbase利用內存完成讀寫操作。提高HBase內存可以有效提高HBase性能。

2.2.1 GC參數

參數值:GC_OPTS

參數解析:

  GC_OPTS主要需要調整HeapSize的大小和NewSize的大小。

  HMaster
    - -Xms512M -Xmx1G -XX:NewSize=64M -XX:MaxNewSize=128M
  RegionServer
    - -Xms4G -Xmx6G -XX:NewSize=64M -XX:MaxNewSize=128M
如何調優?

  A. 調整 HeapSize 大小的時候,建議將 Xms Xmx 設置成相同的值,這樣可以避免 JVM動態調整 HeapSize 大小的時候影響性能。

  B. 調整 NewSize 大小的時候,建議把其設置為 HeapSize 大小的 1/9

  CHMaster:當 HBase 集群規模越大、 Region 數量越多時,可以適當調大 HMaster GC_OPTS 參數。

  DRegionServerRegionServer 需要的內存一般比 HMaster 要大。在內存充足的情況下,HeapSize 可以相對設置大一些。

經驗設定:

HMaster HeapSize 4G 的時候, HBase 集群可以支持 100000Region 數的規模。根據經驗值,單個 RegionServer HeapSize 不建議超過 20GB 

 

2.3 緩存相關

  參數值:hfile.block.cache.size

  參數解析:

    HBase緩存區大小,主要影響查詢性能。根據查詢模式以及查詢記錄分布情況來解決緩存區的大小。

  如何調優?

    默認:0.25

    如果采用隨機查詢使得緩存區的命中率較低,可以適當降低緩存區大小。

 

3、關鍵參數配置指導--案例

3.1 活躍Region對集群的影響

  HBase在設計上,遵循了LSM-TREE的原理:寫數據階段,盡最大努力先將每一個Region的數據保留在內存(MemStore)中,等達到一定的閾值(默認為128M)之后,再 將這些數據固化(Flush)到文件(HFile)中,在這過程中,為了保證數據的安全性,通過將數據寫入到一個人日志文件(Hlog)中:

在當前時間段可能被寫入用戶數據的Region,稱作“活躍"Region”。

 

舉例:

如果一個用戶表的Region是按天划分的,那么,第一天的用戶數據,只會被寫入到第一天的Region中,則這些Region就是活躍的Region。此時,對於其它天的Region,都處於一種“空閑”的狀態。

 集群中每一個物理節點的內存資源都是有限的,每一個Region的數據都是暫時先保留在內存中然后再固化到HFile文件中的,因此,我們需要控制一個時間段的活躍的Region數目。如果Region過多的話,會導致內存資源緊張,每一個Region在內存中的數據可能還沒有達到預先設置閾值的大小就被提前觸發Flush操作,這會導致Flush頻率升高,產生大量的小HFile(小文件過多會導致讀取性能的直線下降,也會加大Compaction的頻率和壓力)。相反活躍Region過少的話,也會導致並發度提升不上去,讀寫性能偏低

 

如何設置最合理的活躍Region數目?

  需要根據MemStore Flush的閾值大小,以及RegionServer堆內存的大小、預留MemStore空間的大小進行合理的計算。

  如下列子可以說明這種計算方法:

  經驗舉例:

    假設分配給RegionServer堆內存的大小為8G,MemStore所占空間比例為40%,MemStore Flush的閾值大小為128M,則合理的活躍Region數目約為8*1024*0.4/128=26(個/節點)。

    以用戶交易記錄表為例。每一條用戶交易記錄關聯一個USER_ID,也關聯一個確切的交易時間點。

      如果我們在設計Key值的時候,采用“USER_ID+TIME”的格式,則划分Region的時候,一定會按照USER_ID的范圍划分的。對於任意一天的交易記錄,可能涉及到各個范圍內的USER_ID,即可能涉及到所有的Region,因此所有的Region都可能是活躍的,就會導致前面提到的那種活躍Region過多的問題,而且這種問題會隨着時間的持續而不斷惡化下去。

                  

如果RowKey采用格式“DAY+USER_ID_TIME”的話,Region一定是按天划分的,那么,第N天的用戶交易記錄數據只會設計到第N天的Region,也只有這一天的Region是活躍的,這樣就有力的控制了活躍Region數目:

             

4、定位調優

4.1日志收集

日志分類介紹:

  當前HBase的日志保存在/var/log/Bigdata/HBase和/var/log/Bigdata/audit/hbase目錄下,具體如下:

  

         

4、2調優定位

  對於讀寫性能定位和調優,主要查看Regionserver的hbase-XXX-regionserver-XXX.log
行日志。

  日志中是否出現過以下信息?

  **Flush thread woke up with memory above low water.

  日志中出現這個信息說明有部分寫過程出現過阻塞等待的現象,造成這個現象的原因是各個Region的Memstore使用的大小加起來超過了總的閾值,於是阻塞,並開始找一個Region進行Flush,,這個過程會需要消耗掉一段時間,通常來說造成這個的原因是單台Region server上的Region數太多了,因此單台Region server上最好不要放置過多的Region,一種調節方法是調大split的fileSize,這樣可以適當的減少Region數,但需要關注調整后讀性能的變化

  **delaying flush up to

  當日志中出現這個信息時,可能會造成出現下面的現象,從而產生影響,這個通常是StoreFile太多造成的,通常可以調大點StoreFile個數的閾值。

  **Blocking updates for

  當日志中出現這個信息時,表示寫動作已被阻塞,造成這個現象的原因是memStore中使用的大小已超過其閾值的2倍,通常是由於上面的delaving flush up to 造成的,或者是region數太多造成的,或者是太多的Hlog造成的,這種情況下會造成很大的影響,如內存夠用的話,可以調大閾值,如果是其他原因,就對症下葯。

 

4、3、定位調優思路

  針對HBase讀寫變慢的場景,可以按照如下思路進行定位、調優:

  開始-->對比性能差距-->查看監控信息-->查看相關日志-->確定具體場景-->進行參數調優-->后續觀察

4.3.1通過客戶端程序,記錄寫入、讀取速度

  在客戶端程序中,可以記錄HBase寫入/讀取速度,關注性能差距。或者,通過HMaster的頁面來查看各個RegionServer的RPC請求。

       

4.3.2查看HBase監控信息

  Region的分裂、compaction、flush次數過多、flush耗時高、硬件資源搶占等眾多元素都會影響性能,因此,需要從Manager監控頁面中,查看各個RegionServer的各類監控指標,需要重點關注:RegionServer GC時間、RegionServer GC次數、節點CPU/內存利用率、Compaction的次數,Flush文件次數、Flush操作的平均耗時、Split次數等信息。

                

 4.3.3查看相關日志

  結合HBase的監控信息,查看RegionServer的運行日志。

 

4.3.4舉例

4.3.4.1背景說明

某個HBase測試集群,客戶端主要是put寫入操作,發現寫入性能較慢。只有一張hbase表t1,表結構簡單(一個cf,一個qualifier),建表時預分5個Region。

4.3.4.2性能差距比較

通過客戶端put對t1表put數據計算出,單節點寫入速度為416條/s左右。

4.3.4.3監控信息展示

發現各個RegionServer的flush次數較多

RegionServer的內存占用並不高

4.3.4.4日志分析定位

可以查看RegionServer的運行日志,發現Flush被延長90000ms字樣:

2016-04-22 02:35:33,820 | WARN | MemStoreFlusher.0 | Region
t1,04,1461259167461.b6e781003392195313a5ec8e39c6bf77. has too many store files;

delaying flush up to 90000ms |
org.apache.hadoop.hbase.regionserver.MemStoreFlusher.flushRegion(MemStoreFlusher.jav
a:448)

 

初步分析結論:在內存利用不高的情況下,仍然有過多的Flush操作,並且看到有的Flush被延遲。因此,主要根據1.2章節內容,對MemStore相關參數,進行調優。

4.3.4.5參數調整&測試

調整前的參數為:
hbase.regionserver.global.memstore.size=0.1
hbase.hstore.blockingStoreFiles=2
調整后的參數為:
hbase.regionserver.global.memstore.size=0.4
hbase.hstore.blockingStoreFiles=7
調整后,用同樣的客戶端對同一張表 t1 進行 put 寫入測試, 發現寫入性能得到提升, 單
節點處理性能達到 1280 /s

 

4、4常見問題處理

4.4.1 OOM(內存溢出)

4.4.1.1問題現象

當運行bulkload任務或開啟Region操作時,在RegionServer端產生如下的日志:

“java.lang.OutOfMemoryError:Direct buffer memory”

4.4.1.2問題定位過程

由於各種操作,HBase需要許多內存。I/O操作實驗direct buffer memory,因此為了更好的性能和提高並發數需要給RegionServer提供更多的direct buffer memory和heap memory。

檢查JVM參數,按照使用場景增加heap memory(-Xms/-Xmx)和direct buffer memory(-XX:MaxDirectMemorySize)

4.4.1.3問題解決方法

增加heap memory和direct buffer memory來避免OutOfMemory異常

  eg:-Xms32G -Xmx32G -XX:MaxDirectMemorySize=2048M

經驗設定:

  按照使用場景來修改GC_OPTS,RegionServer並發讀寫操作越多,需要的內存越大,經驗表明一般地上述示例配置能支撐單個RegionServer支持30個長期並發的需求。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM