HBase——PerformanceEvaluation(壓測工具)


 

簡介

在項目開發過程中,我們經常需要一些benchmark工具來對系統進行壓測,以獲得系統的性能參數,極限吞吐等等指標。

而在HBase中,就自帶了一個benchmark工具—PerformanceEvaluation,可以非常方便地對HBase的Put、Get、Scan等API進行性能測試,並提供了非常豐富的參數來模擬各種場景。

這篇文章,就以HBbase2.0中的PerformanceEvaluation工具為例,給大家講解一下這款HBase benchmark工具的使用和注意事項。

 

參數介紹

PerformanceEvaluation的全名是org.apache.hadoop.hbase.PerformanceEvaluation. 已經集成在了bin/hbase工具集中。

在安裝好HBase的機器上,在HBase的安裝路徑的bin目錄下執行hbase pe,加上相應參數,即可運行PE工具(以下簡稱PerformanceEvaluation為PE)。

如果不加任何參數,則會輸出PE的幫助信息。

[root@xxxxxx ~]# hbase pe
Usage: java org.apache.hadoop.hbase.PerformanceEvaluation \
  <OPTIONS> [-D<property=value>]* <command> <nclients>

General Options:
 nomapred        采用MapReduce的方式啟動多線程測試還是通過多線程的方式,如果沒有安裝MapReduce,或者不想用MapReduce,通常我們采用多線程的方式,因此一般在命令中加上--nomapred來表示不使用MapReduce。  
 rows            每個客戶端(線程)運行的行。默認值:一百萬。注意這里的行數是指單線程的行數,如果rows=100, 線程數為10,那么在寫測試中,寫入HBase的將是 100 x 10 行  
 size            總大小,單位GiB。與--rows互斥。默認值:1.0。  
 sampleRate      樣本比例:對總行數的一部分樣本執行測試。只有randomRead支持。默認值:1.0  
 traceRate       啟用HTrace跨度。每N行啟動一次跟蹤。默認值:0  
 table           測試表的名字,如果不設,默認為TestTable。  
 multiGet        如果> 0,則在執行RandomRead時,執行多次獲取而不是單次獲取。默認值:0  
 compress        要使用的壓縮類型(GZ,LZO,...)。默認值:''  
 flushCommits    該參數用於確定測試是否應該刷新表。默認值:false  
 writeToWAL      在puts上設置writeToWAL。默認值:True  
 autoFlush       默認為false,即PE默認用的是BufferedMutator,BufferedMutator會把數據攢在內存里,達到一定的大小再向服務器發送,如果想明確測單行Put的寫入性能,建議設置為true。個人覺得PE中引入autoFlush會影響統計的准確性,因為在沒有攢夠足夠的數據時,put操作會立馬返回,根本沒產生RPC,但是相應的時間和次數也會被統計在最終結果里。  
 oneCon          多線程運行測試時,底層使用一個還是多個鏈接。這個參數默認值為false,每個thread都會啟一個Connection,建議把這個參數設為True  
 presplit        表的預分裂region個數,在做性能測試時一定要設置region個數,不然所有的讀寫會落在一個region上,嚴重影響性能  
 inmemory        試圖盡可能保持CF內存的HFile。不保證始終從內存中提供讀取。默認值:false  
 usetags         與KV一起寫標簽。與HFile V3配合使用。默認值:false  
 numoftags       指定所需的標簽號。僅當usetags為true時才有效。  
 filterAll       通過不將任何內容返回給客戶端,幫助過濾掉服務器端的所有行。通過在內部使用FilterAllFilter,幫助檢查服務器端性能。  
 latency         設置為報告操作延遲。默認值:False  
 bloomFilter     Bloom 過濾器類型,[NONE,ROW,ROWCOL]之一  
 valueSize       寫入HBase的value的size,單位是Byte,大家可以根據自己實際的場景設置這個Value的大小。默認值:1024  
 valueRandom     設置是否應該在0和'valueSize'之間改變值大小;設置讀取大小的統計信息:默認值: Not set.  
 valueZipf       設置是否應該以zipf格式改變0和'valueSize'之間的值大小, 默認值: Not set.  
 period          報告每個'period'行:默認值:opts.perClientRunRows / 10  
 multiGet        批處理組合成N組。只有randomRead支持。默認值: disabled  
 replicas        啟用區域副本測試。默認值:1。  
 splitPolicy     為表指定自定義RegionSplitPolicy。  
 randomSleep     在每次獲得0和輸入值之前進行隨機睡眠。默認值:0  

 Note: -D properties will be applied to the conf used.   
  For example:   
   -Dmapreduce.output.fileoutputformat.compress=true  
   -Dmapreduce.task.timeout=60000  

Command:  
 filterScan      使用過濾器運行掃描測試,根據它的值查找特定行(確保使用--rows = 20randomRead  運行隨機讀取測試  
 randomSeekScan  運行隨機搜索和掃描100測試  
 randomWrite  運行隨機寫測試  
 scan            運行掃描測試(每行讀取)  
 scanRange10     使用開始和停止行(最多10行)運行隨機搜索掃描  
 scanRange100    使用開始和停止行運行隨機搜索掃描(最多100行)  
 scanRange1000   使用開始和停止行(最多1000行)運行隨機搜索掃描  
 scanRange10000  使用開始和停止行運行隨機搜索掃描(最多10000行)  
 sequentialRead  運行順序讀取測試  
 sequentialWrite 運行順序寫入測試  

Args:  
 nclients        整數。必須要有該參數。客戶端總數(和HRegionServers)  
running: 1 <= value <= 500  
Examples:  
 運行一個單獨的客戶端:  
 $ bin/hbase org.apache.hadoop.hbase.PerformanceEvaluation sequentialWrite 1 

PE工具的參數非常多,很多參數只是用於某項專門的測試。這里我只介紹一下比較重要的幾個全局參數。

  • nomapred 采用MapReduce的方式啟動多線程測試還是通過多線程的方式,如果沒有安裝MapReduce,或者不想用MapReduce,通常我們采用多線程的方式,因此一般在命令中加上--nomapred來表示不使用MapReduce。
  • oneCon 多線程運行測試時,底層使用一個還是多個連接。這個參數默認值為false,每個thread都會啟一個Connection,建議把這個參數設為True,至於原因,后面的章節會講。
  • valueSize 寫入HBase的value的size,單位是Byte,大家可以根據自己實際的場景設置這個Value的大小。
  • blockEncoding PE工具會自動建表,這個參數用來指定表的block encoding。關於encoding后面會有專門的文章介紹,這里不再講。
  • table 測試表的名字,如果不設,默認為TestTable。
  • rows 總共測試的行數。注意這里的行數是指單線程的行數,如果rows=100, 線程數為10,那么在寫測試中,寫入HBase的將是 100 x 10 行。
  • size 總測試的數據大小,單位為GB,這個參數與上面的size是互斥的,不要兩個參數一起設。在使用randomReads和randomSeekScans測試時,這個size可以用來指定讀取的數據范圍。這個值在Read時非常重要,如果設的不好,會產生很多返回值為空的讀,影響測試結果,下面會詳細介紹。
  • compress 設置表的compress算法,根據自己選擇,默認是None,即不做壓縮。
  • presplit 表的預分裂region個數,在做性能測試時一定要設置region個數,不然所有的讀寫會落在一個region上,嚴重影響性能
  • autoFlush 默認為false,即PE默認用的是BufferedMutator,BufferedMutator會把數據攢在內存里,達到一定的大小再向服務器發送,如果想明確測單行Put的寫入性能,建議設置為true。個人覺得PE中引入autoFlush會影響統計的准確性,因為在沒有攢夠足夠的數據時,put操作會立馬返回,根本沒產生RPC,但是相應的時間和次數也會被統計在最終結果里。

比較重要的參數就這么多,其他的參數要么使用默認就好,要么就是和具體的測試命令相關,用戶可以根據測試的內容具體設置。

 

使用示例

下面我用測試讀和寫兩個示例來講解下PE工具的使用

隨機寫測試 RandomWriteTest

RandomWriteTest常用來評估HBase的寫性能。使用的命令如下:

hbase pe --nomapred --oneCon=true --valueSize=100 --compress=SNAPPY --rows=150000 --autoFlush=true --presplit=64 randomWrite 64

在這個測試中,我把PE模式設為了非MapReduuce(--nomapred),即采用起線程的形式。跑的命令是randomWrite,即隨機寫入、后面跟的64代表起了64個線程來做寫入。

--rows=150000 代表每個線程會寫入150000行數據。其他的參數含義可以參見之前的章節。每次測試都會刪除之前測試創建的測試表。刪除表的時間不計入結果。

PE工具的所有的輸出都會直接寫到LOG文件,LOG的位置需要參照HBase的設置。運行結束后,PE會分別打出每個線程的延遲狀況。如下面是其中一個線程的結果:

2018-05-18 12:07:23,282 INFO  [TestClient-11] hbase.PerformanceEvaluation(475): Latency (us) : mean=2516.36, min=872.00, max=73776.00, stdDev=1978.60, 50th=2304.00, 75th=2605.00, 95th=3418.00, 99th=790
8.00, 99.9th=34241.00, 99.99th=73263.00, 99.999th=73776.00
2018-05-18 12:07:23,282 INFO  [TestClient-11] hbase.PerformanceEvaluation(475): Num measures (latency) : 150000
2018-05-18 12:07:23,283 INFO  [TestClient-11] hbase.PerformanceEvaluation(475): Mean      = 2516.36
Min       = 872.00
Max       = 73776.00
StdDev    = 1978.60
50th      = 2304.00
75th      = 2605.00
95th      = 3418.00
99th      = 7908.00
99.9th    = 34241.00
99.99th   = 73263.00
99.999th  = 73776.00

PE統計了這個線程一共跑了多少行,和相應的延遲統計,包括min,max,999th延遲等等。
並在最后統計了所有線程的最大持續時間,平均持續時間等等。

2018-05-18 12:07:25,564 INFO  [main] hbase.PerformanceEvaluation(507): [RandomWriteTest duration ]      Min: 36969ms    Max: 40160ms    Avg: 38203ms

比較坑的是,PE竟然不會統計所有線程的平均延遲和總的吞吐。

 

隨機讀測試 RandomReadTest

在進行RandomReadTest之前,需要准備數據。准備數據建議使用SequentialWriteTest。如下面的語句

hbase pe --nomapred --oneCon=true --valueSize=100 --compress=SNAPPY --size=2 --presplit=64 sequentialWrite 64

為啥要用SequentialWriteTest?

這是因為PE寫入的行是有規律的。如果傳入的是--row=1000(代表每個線程會寫1000次),thread數是10,則寫入的行總數是1000 x 10 = 10000。在SequentialWrite中,PE會給每個線程設置偏移量,

保證0~9999這10000個行(會把所有數字擴展成26位等長的byte數組)一行不差地寫入HBase。如果是RandomWriteTest,在每個線程中會隨機生成一個0~9999之前的數字寫入。

由於是隨機,會造成中間有些行沒有寫入,那么在讀取測試時,讀到的就是空行,影響測試結果。

為啥要用--size而不是--row?

--size=2,代表寫入2GB數據,具體是多少行PE內部會自己去算。假設我這里填的是--row=1000,線程數是10,那么寫入的數據范圍是0~9999。

當我在做RandomReadTest時,如果需要修改線程數,比如我想測20個線程並行讀,那么數據讀取的范圍將是0~ (1000 * 20 - 1), 很大一部分讀是空讀!

你當然可以根據線程數來調整讀測試時row變量的值,使讀的整體范圍不超過寫入的數據范圍,但是row的大小影響了整體測試的時間,而統一用size你就啥都不用管了。
RandomReadTest的命令如下:

hbase pe --nomapred --oneCon=true --valueSize=100 --size=2  randomRead 100

注意在讀測試時不要加表的任何參數,如presplit這些,如果加了會使PE重新建表,之前寫入的數據就拜拜了。

valueSize和size的值要與准備數據命令中保持一致,PE靠這兩個值來算數據的范圍和行數。Read測試的輸出與Write測試的輸出類似。

 

PE工具存在的問題

PE工具雖然功能已經比較完備,但是使用下來發現還是存在一定的問題的,主要有以下幾點:

  1. Connection的數目設置只能由oneCon這個參數指定,要么就是一個connection,要么就是每個thread一個connection。當測試的線程數比較多時,就比較尷尬了,如果只用一個connection,connection內部的metaCache等實現都是有鎖的,在拿metacache時,線程較多會產生爭搶,影響對服務器性能的評估。如果每個thread一個connection更加不可取,每個connection中都會有一個netty的客戶端,如果我沒記錯的話,每個客戶端中將會有 2*CPU個worker threads。這在PE運行過程中產生大量的context switch,更加影響性能測試。根據我的測試發現,在開100個thread測試時,如果每個thread開一個connection,測試結果比只用一個connection的要慢10%。Context switch的頻率更是10倍以上。
  2. 沒有multiPut的支持,PE寫時使用的BufferedMutator需要靠調整size來決定buffer多少個put再上發。如果我想明確測試batch 5個put請求,batch10個put請求,都比較難實現。
  3. 沒有統計總體的RT和TPS/QPS,只有按單個thread統計,如果我用100個thread去壓服務器,這要我怎么去評估服務器的吞吐……

針對以上的問題,具體大家可以看HBASE-20601這個issue。主要的改進有:

  1. 加入multiPut參數,支持設置batch的數量
  2. 加入connCount參數,支持設置connection的多少,比如connCount=2,不管多少個thread都會共用這2個connection
  3. 支持統計所有線程的平均TPS,平均延遲
  4. 一些代碼的優化和去重

 

 

引用:


免責聲明!

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



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