Hbase性能測試
一、涉及調優參數
1、表的設計
1.1、Pre-Creating Regions
默認情況下,在創建HBase表的時候會自動創建一個region分區,當導入數據的時候,所有的HBase客戶端都向這一個region寫數據,直到這個region足夠大了才進行切分。
一種可以加快批量寫入速度的方法是通過預先創建一些空的regions,這樣當數據寫入HBase時,會按照region分區情況,在集群內做數據的負載均衡。
1.2、Compact & Split
在HBase中,數據在更新時首先寫入WAL 日志(HLog)和內存(MemStore)中,MemStore中的數據是排序的,當MemStore累計到一定閾值時,就會創建一個新的MemStore,並且將老的MemStore添加到flush隊列,由單獨的線程flush到磁盤上,成為一個StoreFile。於此同時, 系統會在zookeeper中記錄一個redo point,表示這個時刻之前的變更已經持久化了(minor compact)。
StoreFile是只讀的,一旦創建后就不可以再修改。因此Hbase的更新其實是不斷追加的操作。當一個Store中的StoreFile達到一定的閾值后,就會進行一次合並(major compact),將對同一個key的修改合並到一起,形成一個大的StoreFile,當StoreFile的大小達到一定閾值后,又會對 StoreFile進行分割(split),等分為兩個StoreFile。
由於對表的更新是不斷追加的,處理讀請求時,需要訪問Store中全部的StoreFile和MemStore,將它們按照row key進行合並,由於StoreFile和MemStore都是經過排序的,並且StoreFile帶有內存中索引,通常合並過程還是比較快的。
實際應用中,可以考慮必要時手動進行major compact,將同一個row key的修改進行合並形成一個大的StoreFile。同時,可以將StoreFile設置大些,減少split的發生。
1.3、壓縮方式
在hadoop和hbase文件傳輸可以在壓縮之后在進行傳輸,這樣就可以在傳輸的時候減少傳輸數據,增大I/O和帶寬效率。在hadoop中主要提供了三種壓縮方式Gzip、LZO、Snappy三種數據壓縮。
實際使用中,可以考慮分別嘗試兩種壓縮模式,選出最適合業務場景要求的。
2、寫表操作
2.1、Row Key設計
HBase中row key用來檢索表中的記錄,支持以下三種方式:
- 通過單個row key訪問:即按照某個row key鍵值進行get操作;
- 通過row key的range進行scan:即通過設置startRowKey和endRowKey,在這個范圍內進行掃描;
- 全表掃描:即直接掃描整張表中所有行記錄。
row key是按照字典序存儲,因此,設計row key時,要充分利用這個排序特點,將經常一起讀取的數據存儲到一塊,將最近可能會被訪問的數據放在一塊。
如果最近寫入HBase表中的數據是最可能被訪問的,可以考慮將時間戳作為row key的一部分,由於是字典序排序,所以可以使用Long.MAX_VALUE – timestamp作為row key,這樣能保證新寫入的數據在讀取時可以被快速命中。
2.2、多HTable並發寫
創建多個HTable客戶端用於寫操作,提高寫數據的吞吐量,
2.3、HTable參數設置
2.3.1 Auto Flush
通過調用HTable.setAutoFlush(false)方法可以將HTable寫客戶端的自動flush關閉,這樣可以批量寫入數據到HBase,而不是有一條put就執行一次更新,只有當put填滿客戶端寫緩存時,才實際向HBase服務端發起寫請求。默認情況下auto flush是開啟的。
2.3.2 Write Buffer
通過調用HTable.setWriteBufferSize(writeBufferSize)方法可以設置HTable客戶端的寫buffer大小,如果新設置的buffer小於當前寫buffer中的數據時,buffer將會被flush到服務端。其中,writeBufferSize的單位是byte字節數,可以根據實際寫入數據量的多少來設置該值。
2.3.3 WAL Flag
在HBae中,客戶端向集群中的RegionServer提交數據時(Put/Delete操作),首先會先寫WAL(Write Ahead Log)日志(即HLog,一個RegionServer上的所有Region共享一個HLog),只有當WAL日志寫成功后,再接着寫MemStore,然后客戶端被通知提交數據成功;如果寫WAL日志失敗,客戶端則被通知提交失敗。這樣做的好處是可以做到RegionServer宕機后的數據恢復。
因此,對於相對不太重要的數據,可以在Put/Delete操作時,通過調用Put.setWriteToWAL(false)或Delete.setWriteToWAL(false)函數,放棄寫WAL日志,從而提高數據寫入的性能。
3、讀表操作
3.1 多HTable並發讀
創建多個HTable客戶端用於讀操作,提高讀數據的吞吐量,
3.3 批量讀
通過調用HTable.get(Get)方法可以根據一個指定的row key獲取一行記錄,同樣HBase提供了另一個方法:通過調用HTable.get(List)方法可以根據一個指定的row key列表,批量獲取多行記錄,這樣做的好處是批量執行,只需要一次網絡I/O開銷,這對於對數據實時性要求高而且網絡傳輸RTT高的情景下可能帶來明顯的性能提升。
3.4 多線程並發讀
在客戶端開啟多個HTable讀線程,每個讀線程負責通過HTable對象進行get操作。
3.5 緩存查詢結果
對於頻繁查詢HBase的應用場景,可以考慮在應用程序中做緩存,當有新的查詢請求時,首先在緩存中查找,如果存在則直接返回,不再查詢HBase;否則對HBase發起讀請求查詢,然后在應用程序中將查詢結果緩存起來。至於緩存的替換策略,可以考慮LRU等常用的策略。
3.6 Blockcache
HBase上Regionserver的內存分為兩個部分,一部分作為Memstore,主要用來寫;另外一部分作為BlockCache,主要用於讀。
寫請求會先寫入Memstore,Regionserver會給每個region提供一個Memstore,當Memstore滿64MB以后,會啟動 flush刷新到磁盤。當Memstore的總大小超過限制時(heapsize * hbase.regionserver.global.memstore.upperLimit * 0.9),會強行啟動flush進程,從最大的Memstore開始flush直到低於限制。
讀請求先到Memstore中查數據,查不到就到BlockCache中查,再查不到就會到磁盤上讀,並把讀的結果放入BlockCache。由於BlockCache采用的是LRU策略,因此BlockCache達到上限(heapsize * hfile.block.cache.size * 0.85)后,會啟動淘汰機制,淘汰掉最老的一批數據。
一個Regionserver上有一個BlockCache和N個Memstore,它們的大小之和不能大於等於heapsize * 0.8,否則HBase不能啟動。默認BlockCache為0.2,而Memstore為0.4。對於注重讀響應時間的系統,可以將 BlockCache設大些,比如設置BlockCache=0.4,Memstore=0.39,以加大緩存的命中率。
二、測試環境
2.1測試組網
2.2設備配置
軟件配置
軟件名稱 |
軟件版本 |
數量(套) |
說明 |
Hadoop |
2.2.0 |
1 |
|
HBase |
HBase-0.96 |
1 |
|
硬件配置
序號 |
設備名稱 |
數量 |
CPU |
內存 |
硬盤 |
說明 |
1 |
主控服務器 |
2 |
I2-2100/雙核四線程 |
4G |
500G |
|
2 |
處理節點 |
7 |
I5-2320 |
16G |
1T |
|
網絡配置
序號 |
設備名稱 |
設備型號 |
數量 |
1 |
千兆交換機 |
SD2008T |
1 |
2 |
千兆連接口 |
10/100/1000BASE-T口 |
24 |
2.3測試工具
2.3.1 Ganglia監控工具
Ganglia是設計用於檢測數以千計的節點。Ganglia的核心包含gmond、gmetad以及一個Web前端。主要是用來監控系統性能,如:cpu 、mem、硬盤利用率, I/O負載、網絡流量情況等,通過曲線很容易見到每個節點的工作狀態,對合理調整、分配系統資源,提高系統整體性能起到重要作用。
2.4測試方法
HBase測試是采用YCSB benchmark測試的,HBase入庫數據量:5000萬條、1億條、5億條、10億條、20億、40億、80億、100億條;HBase數據查詢是采用測試代碼實現的,本次HBase查詢是以行鍵+列族+列名進行數據查詢的。
數據立方(Datacube)數據入庫分別將HBase中的5000萬、1億條、5億條、10億條、20億、40億、80億、100億條數據,以文本格式導入到數據立方hdfs中的。數據立方中的查詢條件與HBase中的查詢條件相同。
三、用例設計
1、HBase可靠性測試
1.1、Hadoop(NameNode)節點故障
項目 |
HBase |
用例名稱 |
主namenode宕機 |
用例編號 |
HBase-fun-001 |
重要性 |
重要 |
測試目的 |
驗證主namenode宕機后, 備namenode節點是否能正常轉換為主節點,並且系統穩定運行 |
||
預置條件 |
1、 HBase運行正常 2、 客戶端運行正常 |
||
測試步驟 |
1、客戶端向HBase寫數據 2、寫數據過程中,構造主節點服務器故障:重啟(reboot)、網絡異常、掉電、服務關閉 3、檢測寫入的數據是否丟失 |
||
預期結果 |
1、NameNode2自動切換為active,且系統穩定。切換完成時間少於10s 2、數據寫入成功 3、切換后寫入的數據無丟失 |
||
備注 |
|
1.2、Hadoop(DataNode)節點故障
項目 |
HBase |
用例名稱 |
寫數據過程中datanode節點宕機 |
用例編號 |
HBase-fun-002 |
重要性 |
重要 |
測試目的 |
驗證客戶端向HBase寫入數據過程中,將datanode故障情況下,測試寫入的數據是否成功 |
||
預置條件 |
HBase運行正常 客戶端運行正常 設置副本數為2 |
||
測試步驟 |
1、客戶端向HBase寫數據 2、寫數據過程中,構造datanode節點服務器故障:重啟(reboot)、網絡異常、掉電、服務關閉 3、檢測數據寫入是否成功 |
||
預期結果 |
寫數據過程中,在機器宕機的那一瞬間寫入的某個文件寫失敗,之后的數據寫入成功 |
||
備注 |
|
1.3、Hbase(Hmaster)節點故障
項目 |
HBase |
用例名稱 |
寫數據過程中Hmaster節點宕機 |
用例編號 |
HBase-fun-002 |
重要性 |
重要 |
測試目的 |
驗證客戶端向HBase寫入數據過程中,將Hmaster故障情況下,測試寫入的數據是否成功 |
||
預置條件 |
HBase運行正常 客戶端運行正常 設置副本數為2 |
||
測試步驟 |
1、客戶端向HBase寫數據 2、寫數據過程中,構造Hmaster節點服務器故障:重啟(reboot)、網絡異常、掉電、服務關閉 3、檢測數據寫入是否成功 |
||
預期結果 |
寫數據過程中,在機器宕機的那一瞬間寫入的某個文件寫失敗,之后的數據寫入成功 |
||
備注 |
|
1.4、Hbase(RegionServer)節點故障
項目 |
HBase |
用例名稱 |
寫數據過程中RegionServer節點宕機 |
用例編號 |
HBase-fun-002 |
重要性 |
重要 |
測試目的 |
驗證客戶端向HBase寫入數據過程中,將RegionServer故障情況下,測試寫入的數據是否成功 |
||
預置條件 |
HBase運行正常 客戶端運行正常 設置副本數為2 |
||
測試步驟 |
1、客戶端向HBase寫數據 2、寫數據過程中,構造RegionServer節點服務器故障:重啟(reboot)、網絡異常、掉電、服務關閉 3、檢測數據寫入是否成功 |
||
預期結果 |
寫數據過程中,在機器宕機的那一瞬間寫入的某個文件寫失敗,之后的數據寫入成功 |
||
備注 |
|
2、HBase入庫性能
2.1、單客戶端數據入庫
項目 |
HBase |
用例名稱 |
單個客戶端入庫性能測試 |
用例編號 |
HBase-pre-001 |
重要性 |
重要 |
測試目的 |
驗證單個客戶端向HBase中寫數據,通過ganglia監控工具,獲知單個客戶端數據入庫帶寬 |
||
預置條件 |
HBase運行正常 客戶端運行正常 |
||
測試步驟 |
1、啟用單個客戶端向HBase連續寫入5億條數據 2、啟用ganglia監控程序 3、記錄數據入庫速率 |
||
預期結果 |
1、數據入庫正確無誤 2、數據入庫速率正常 |
||
備注 |
|
2.2、多客戶端數據入庫速率
項目 |
HBase |
用例名稱 |
多個客戶端入庫性能測試 |
用例編號 |
HBase-pre-002 |
重要性 |
重要 |
測試目的 |
驗證多個客戶端向HBase中寫數據,通過ganglia監控工具,獲知多個客戶端數據入庫帶寬 |
||
預置條件 |
HBase運行正常 客戶端運行正常 |
||
測試步驟 |
1、啟用多個客戶(不同服務器)並發向HBase寫5億條數據 2、啟用ganglia系統監控程序 3、記錄數據庫入庫速率 |
||
預期結果 |
1、數據入庫正確無誤 2、多個客戶端數據入庫速率正常 |
||
備注 |
|
2.3、5000萬條記錄入庫測試
項目 |
HBase |
用例名稱 |
HBase5000萬條記錄入庫測試 |
用例編號 |
HBase-pre-003 |
重要性 |
重要 |
測試目的 |
測試統計5000萬條記錄寫到HBase中所用的時長 |
||
預置條件 |
HBase運行正常 客戶端運行正常 |
||
測試步驟 |
1、客戶端通過Benchmark向HBase寫入5000萬記錄 2、記錄5000萬條記錄入庫時長 |
||
預期結果 |
1、記錄入庫正確 2、5000萬條記錄入庫時長正常 |
||
備注 |
|
2.4、1億條記錄入庫測試
項目 |
HBase |
用例名稱 |
HBase中1億條記錄入庫測試 |
用例編號 |
HBase-pre-004 |
重要性 |
重要 |
測試目的 |
測試統計1億條記錄寫到HBase中所用的時長 |
||
預置條件 |
1、 HBase運行正常 2、 客戶端運行正常 |
||
測試步驟 |
1、客戶端通過Benchmark向HBase寫入1億條記錄 2、記錄1億條記錄入庫時長 |
||
預期結果 |
1、記錄入庫正確 2、1億條記錄入庫時長正常 |
||
備注 |
|
2.5、5億條記錄入庫測試
項目 |
HBase |
用例名稱 |
HBase中5億條記錄入庫測試 |
用例編號 |
HBase-pre-005 |
重要性 |
重要 |
測試目的 |
測試統計5億條記錄寫到HBase中所用的時長 |
||
預置條件 |
HBase運行正常 客戶端運行正常 |
||
測試步驟 |
1、客戶端通過Benchmark向HBase寫入5億條記錄 2、記錄5億條記錄入庫時長 |
||
預期結果 |
1、記錄入庫正確 2、5億條記錄入庫時長正常 |
||
備注 |
|
2.6、10億條記錄入庫測試
項目 |
HBase |
用例名稱 |
HBase中10億條記錄入庫測試 |
用例編號 |
HBase-pre-006 |
重要性 |
重要 |
測試目的 |
測試統計10億條記錄寫到HBase中所用的時長 |
||
預置條件 |
HBase運行正常 客戶端運行正常 |
||
測試步驟 |
1、客戶端通過Benchmark向HBase寫入10億條記錄 2、記錄10億條記錄入庫時長 |
||
預期結果 |
1、記錄入庫正確 2、10億條記錄入庫時長正常 |
||
備注 |
|
2.7、20億條記錄入庫測試
項目 |
HBase |
用例名稱 |
HBase中20億條記錄入庫測試 |
用例編號 |
HBase-pre-007 |
重要性 |
重要 |
測試目的 |
測試統計20億條記錄寫到HBase中所用的時長 |
||
預置條件 |
HBase運行正常 客戶端運行正常 |
||
測試步驟 |
1、客戶端通過Benchmark向HBase寫入20億條記錄 2、記錄20億條記錄入庫時長 |
||
預期結果 |
1、記錄入庫正確 2、20億條記錄入庫時長正常 |
||
備注 |
|
2.8、40億條記錄入庫測試
項目 |
HBase |
用例名稱 |
HBase中40億條記錄入庫測試 |
用例編號 |
HBase-pre-008 |
重要性 |
重要 |
測試目的 |
測試統計40億條記錄寫到HBase中所用的時長 |
||
預置條件 |
HBase運行正常 客戶端運行正常 |
||
測試步驟 |
1、客戶端通過Benchmark向HBase寫入40億條記錄 2、記錄40億條記錄入庫時長 |
||
預期結果 |
1、記錄入庫正確 2、40億條記錄入庫時長正常 |
||
備注 |
|
2.9、80億條記錄入庫測試
項目 |
HBase |
用例名稱 |
HBase中80億條記錄入庫測試 |
用例編號 |
HBase-pre-009 |
重要性 |
重要 |
測試目的 |
測試統計80億條記錄寫到HBase中所用的時長 |
||
預置條件 |
HBase運行正常 客戶端運行正常 |
||
測試步驟 |
1、客戶端通過Benchmark向HBase寫入80億條記錄 2、記錄80億條記錄入庫時長 |
||
預期結果 |
1、數據入庫正確 2、80億條記錄入庫時長正常 |
||
備注 |
|
2.10、100億條記錄入庫測試
項目 |
HBase |
用例名稱 |
HBase中100億條記錄入庫測試 |
用例編號 |
HBase-pre-010 |
重要性 |
重要 |
測試目的 |
測試統計100億條記錄寫到HBase中所用的時長 |
||
預置條件 |
HBase運行正常 客戶端運行正常 |
||
測試步驟 |
1、客戶端通過Benchmark向HBase寫入100億條記錄 2、記錄100億條記錄入庫時長 |
||
預期結果 |
1、記錄入庫正確 2、100億條記錄入庫時長正常 |
||
備注 |
|
3、HBase查詢性能測試
3.1、5000萬記錄中查詢10條記錄
項目 |
HBase |
用例名稱 |
從5000萬記錄中查詢10條記錄 |
用例編號 |
HBase-pre-011 |
重要性 |
重要 |
測試目的 |
查詢HBase的5000萬條記錄中的10條記錄,查詢10條記錄正確、時間正常 |
||
預置條件 |
HBase運行正常 客戶端運行正常 |
||
測試步驟 |
1、客戶端向HBase寫入5000萬條記錄,其中1條命中 2、通過測試程序發送查詢記錄請求: 3、記錄查詢時長 |
||
預期結果 |
1、查詢結果正確 2、查詢時間正常 |
||
備注 |
|
3.2、1億條記錄中查詢1條記錄
項目 |
HBase |
用例名稱 |
1億條記錄中查詢1條記錄 |
用例編號 |
HBase-pre-012 |
重要性 |
重要 |
測試目的 |
查詢HBase的1億條記錄中的1條記錄,查詢1條記錄正確、時間正常 |
||
預置條件 |
HBase運行正常 客戶端運行正常 |
||
測試步驟 |
1、客戶端向HBase寫入1億條記錄 2、通過測試程序發送查詢記錄請求: 3、記錄查詢時長 |
||
預期結果 |
1、查詢結果正確 2、查詢時間正常 |
||
備注 |
|
3.3、1億條記錄中查詢10條記錄
項目 |
HBase |
用例名稱 |
1億條記錄中查詢10條記錄 |
用例編號 |
HBase-pre-013 |
重要性 |
重要 |
測試目的 |
查詢HBase的1億條記錄中的10條記錄,查詢10條記錄正確、時間正常 |
||
預置條件 |
HBase運行正常 客戶端運行正常 |
||
測試步驟 |
1、客戶端向HBase寫入1億條記錄 2、發送數據查詢10條記錄請求: 3、記錄查詢10條記錄時長 |
||
預期結果 |
1、查詢結果正確 2、查詢時間正常 |
||
備注 |
|
3.4、5億條記錄中查詢1條記錄
項目 |
HBase |
用例名稱 |
1億條記錄中查詢1條記錄 |
用例編號 |
HBase-pre-014 |
重要性 |
重要 |
測試目的 |
查詢HBase的5億條記錄中的1條記錄,查詢1條記錄正確、時間正常 |
||
預置條件 |
HBase運行正常 客戶端運行正常 測試程序運行正常 |
||
測試步驟 |
1、客戶端向HBase寫入5億條記錄 2、通過測試程序發送查詢1條記錄請求: 3、記錄查詢1條記錄時長 |
||
預期結果 |
1、查詢結果正確 2、查詢時間正常 |
||
備注 |
|
3.5、5億條記錄中查詢10條記錄
項目 |
HBase |
用例名稱 |
5億條記錄中查詢10條記錄 |
用例編號 |
HBase-pre-015 |
重要性 |
重要 |
測試目的 |
查詢HBase的5億條記錄中的10條記錄,查詢10條記錄正確、時間正常 |
||
預置條件 |
HBase運行正常 客戶端運行正常 測試代碼運行正常 |
||
測試步驟 |
1、客戶端向HBase寫入5億條記錄 2、運行測試程序發送查詢10條記錄請求: 3、記錄查詢10條記錄時長 |
||
預期結果 |
1、查詢結果正確 2、查詢時間正常 |
||
備注 |
|
3.6、10億條記錄中查詢1000條記錄
項目 |
HBase |
用例名稱 |
10億條記錄中查詢1000條記錄 |
用例編號 |
HBase-pre-016 |
重要性 |
重要 |
測試目的 |
查詢HBase的10億條記錄中的1000條記錄,查詢1000條記錄正確、時間正常 |
||
預置條件 |
HBase運行正常 客戶端運行正常 測試代碼運行正常 |
||
測試步驟 |
1、客戶端向HBase寫入10億條記錄 2、運行測試程序發送查詢1000條記錄請求: 3、記錄查詢1000條記錄時長 |
||
預期結果 |
1、1000條記錄查詢結果正確 2、1000條記錄查詢時間正常 |
||
備注 |
|
3.7、20億條記錄中查詢1000條記錄
項目 |
HBase |
用例名稱 |
20億條記錄中查詢1000條記錄 |
用例編號 |
HBase-pre-017 |
重要性 |
重要 |
測試目的 |
查詢HBase的20億條記錄中的1000條記錄,查詢1000條記錄正確、時間正常 |
||
預置條件 |
HBase運行正常 客戶端運行正常 測試代碼運行正常 |
||
測試步驟 |
1、客戶端向HBase寫入20億條記錄 2、運行測試程序發送查詢1000條記錄請求: Select (1000個RowKey) 3、記錄查詢1000條記錄時長 |
||
預期結果 |
1、1000條記錄查詢結果正確 2、記下1000條記錄查詢時間 |
||
備注 |
|
3.8、40億條記錄中查詢1000條記錄
項目 |
HBase |
用例名稱 |
40億條記錄中查詢1000條記錄 |
用例編號 |
HBase-pre-018 |
重要性 |
重要 |
測試目的 |
查詢HBase的40億條記錄中的1000條記錄,查詢1000條記錄正確、時間正常 |
||
預置條件 |
HBase運行正常 客戶端運行正常 測試代碼運行正常 |
||
測試步驟 |
1、客戶端向HBase寫入40億條記錄 2、運行測試程序發送查詢1000條記錄請求: Select (1000個RowKey) 3、記錄查詢1000條記錄時長 |
||
預期結果 |
1、1000條查詢結果正確 2、統計1000條記錄查詢時間 |
||
備注 |
|
3.9、80億條記錄中查詢1000條記錄
項目 |
HBase |
用例名稱 |
80億條記錄中查詢1000條記錄 |
用例編號 |
HBase-pre-019 |
重要性 |
重要 |
測試目的 |
查詢HBase的80億條記錄中的1000條記錄,查詢1000條記錄正確、時間正常 |
||
預置條件 |
HBase運行正常 客戶端運行正常 測試代碼運行正常 |
||
測試步驟 |
1、客戶端向HBase寫入80億條記錄 2、運行測試程序發送查詢1000條記錄請求: Select (1000個RowKey) 3、記錄查詢1000條記錄時長 |
||
預期結果 |
1、1000條記錄查詢結果正確 2、統計1000條記錄查詢時間 |
||
備注 |
|
3.10、100億條記錄中查詢1000條記錄
項目 |
HBase |
用例名稱 |
100億條記錄中查詢1000條記錄 |
用例編號 |
HBase-pre-020 |
重要性 |
重要 |
測試目的 |
查詢HBase的100億條記錄中的1000條記錄,查詢1000條記錄正確、時間正常 |
||
預置條件 |
HBase運行正常 客戶端運行正常 測試代碼運行正常 |
||
測試步驟 |
1、客戶端向HBase寫入100億條記錄 2、運行測試程序發送查詢1000條記錄請求: Select (1000個RowKey) 3、記錄查詢1000條記錄時長 |
||
預期結果 |
1、1000條記錄查詢結果正確 2、統計1000條記錄查詢時間 |
||
備注 |
|