HBase2.0中的Benchmark工具—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 Run multiple clients using threads (rather than use mapreduce)
oneCon all the threads share the same connection. Default: False
sampleRate Execute test on a sample of total rows. Only supported by randomRead. Default: 1.0
period Report every `period` rows: Default: opts.perClientRunRows / 10 = 104857
cycles How many times to cycle the test. Defaults: 1.
traceRate Enable HTrace spans. Initiate tracing every N rows. Default: 0
latency Set to report operation latencies. Default: False
measureAfter Start to measure the latency once `measureAfter` rows have been treated. Default: 0
valueSize Pass value size to use: Default: 1000
valueRandom Set if we should vary value size between 0 and `valueSize`; set on read for stats on size: Default: Not set.
blockEncoding Block encoding to use. Value should be one of [NONE, PREFIX, DIFF, FAST_DIFF, ROW_INDEX_V1]. Default: NONE
...(後面還有很長)
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,thread數是10,則寫入的行總數是1000 x 10 = 10000。在SequentialWrite中,PE會給每個執行緒設定偏移量,保證0~9999這10000個行(會把所有數字擴充套件成26位等長的byte陣列)一行不差地寫入HBase。如果是RandomWriteTest,在每個執行緒中會隨機生成一個0~9999之前的數字寫入(–row=1000代表每個執行緒會寫1000次)。由於是隨機,會造成中間有些行沒有寫入,那麼在讀取測試時,讀到的就是空行,影響測試結果。
為啥要用–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工具雖然功能已經比較完備,但是使用下來發現還是存在一定的問題的,主要有以下幾點:
- 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倍以上。
- 沒有multiPut的支援,PE寫時使用的BufferedMutator需要靠調整size來決定buffer多少個put再上發。如果我想明確測試batch 5個put請求,batch10個put請求,都比較難實現。
- 沒有統計總體的RT和TPS/QPS,只有按單個thread統計,如果我用100個thread去壓伺服器,這要我怎麼去評估伺服器的吞吐……
針對以上的問題,我對PerformanceEvaluation工具做了一些改進,回饋給了社群,具體大家可以看HBASE-20601這個issue。主要的改進有:
- 加入multiPut引數,支援設定batch的數量
- 加入connCount引數,支援設定connection的多少,比如connCount=2,不管多少個thread都會共用這2個connection
- 支援統計所有執行緒的平均TPS,平均延遲
- 一些程式碼的優化和去重
大家在PE工具的使用過程中還遇到了什麼問題,或者有什麼不懂的地方,歡迎與我聯絡。
雲端使用
阿里HBase目前已經在阿里雲提供商業化服務,任何有需求的使用者都可以在阿里雲端使用深入改進的、一站式的HBase服務。雲HBase版本與自建HBase相比在運維、可靠性、效能、穩定性、安全、成本等方面均有很多的改進,更多內容歡迎大家關注 https://www.aliyun.com/product/hbase
相關文章
- ActiveMQ壓力測試工具(emqtt_benchmark和jmeter)MQQTJMeter
- c++效能測試工具:google benchmark入門(二)C++Go
- c++效能測試工具:google benchmark進階(一)C++Go
- benchmark和baseline的區別
- 如果你想寫自己的Benchmark框架框架
- nosql redis資料庫壓力測試基準工具redis-benchmarkSQLRedis資料庫
- maskrcnn-benchmark 工程配置CNN
- benchmark 基準測試
- 消滅毛刺!HBase2.0全鏈路offheap效果拔群
- VIFB:A Visible and Infrared Image Fusion Benchmark
- JMH Benchmark 效能測試淺談
- JMH- benchmark基準測試
- benchmark 壓測Oracle 11gOracle
- benchmark 壓測Oracle 12cOracle
- 關於HBase2.0,看這一篇文章就夠了
- Go benchmark 一清二楚Go
- 2015年5月移動遊戲Benchmark遊戲
- 使用 Benchmark.NET 測試程式碼效能
- golang 效能優化分析:benchmark 結合 pprofGolang優化
- windows中好用的工具Windows
- 編譯 GPGPU-Sim benchmark ispass2009-benchmarks編譯GPU
- gout v0.0.4釋出,新增介面benchmark功能Go
- 主流開源分散式圖資料庫 Benchmark分散式資料庫
- Paper Reading: JailbreakBench: An Open Robustness Benchmark for Jailbreaking Large Language ModelsAI
- Photoshop中的漸變工具
- OI 中的小技巧(工具)
- 淺談jQuery中的工具方法jQuery
- 工作中那些有用的工具
- Express 工具庫中的 Application 物件ExpressAPP物件
- 壓力測試redis redis-benchmark 優化實踐Redis優化
- 【redis】使用redis benchmark評估哨兵模式主節點效能Redis模式
- 關於BenchMark/c++11計時器/Chrome:tracing 的一些筆記C++Chrome筆記
- Go十大常見錯誤第2篇:benchmark效能測試的坑Go
- CAD繪圖工具中的圓命令繪圖
- CAD繪圖工具中的點命令繪圖
- JDK中自帶的JVM分析工具JDKJVM
- Vue 原始碼中的工具函式Vue原始碼函式
- RLHF · PBRL | 發現部分 D4RL tasks 不適合做 offline reward learning 的 benchmark