HBase性能深度分析

http://www.programmer.com.cn/7246/

文/劉星

HBase作爲BigTable的一個開源實現,隨着其應用的普及,用戶對它的性能數據愈發關注。本文將爲您揭開HBase性能測試的一角,邀您一起參與到對雲計算模塊性能調優的深度思考中。

對於BigTable類型的分佈式數據庫應用來說,用戶往往會對其性能狀況有極大的興趣,這其中又對實時數據插入性能更爲關注。HBase作爲BigTable的一個實現,在這方面的性能會如何呢?這就需要通過測試數據來說話了。

趨勢科技中國研發中心資深QA,在六年職業 生涯中,開發和測試的經驗恰好參半。2009年 加入趨勢科技至今,一直從事基於HBase的分 布式存儲數據庫的研發。
劉星 趨勢科技中國研發中心資深QA,2009年 加入趨勢科技至今,一直從事基於HBase的分佈式存儲數據庫的研發。

數據插入性能測試的設計場景是這樣的:取隨機值的Rowkey長度爲2000字節,固定值的Value長度爲4000字節,由於單行Row插入速度太快,系統統計精度不夠,所以將插入500行Row做一次耗時統計。

這裏要對HBase的特點做個說明,首先是Rowkey值爲何取隨機數,這是因爲HBase是對Rowkey進行排序的,隨機Rowkey將被分配到不同的region上,這樣才能發揮出分佈式數據庫的性能優點。而Value對於HBase來說不會進行任何解析,其數據是否變化,對性能是不應該有任何影響的。同時爲了簡單起見,所有的數據都將只插入到一個表格的同一個Column中。

初次分析

在測試之初,需要對集羣進行調優,關閉可能大量耗費內存、帶寬以及CPU的服務(例如Apache的HTTP服務),保持集羣的寧靜度。此外,爲了保證測試不受干擾,HBase的集羣系統需要被獨立,以保證不與HDFS所在的Hadoop集羣有所交叉。

實驗

那麼做好一切準備之後,就開始進行數據灌入,客戶端從Zookeeper上查詢到Regionserver的地址後,開始源源不斷地向HBase的Regionserver上喂入Row。

這裏,我寫了一個通過JFreeChart來實時生成圖片的程序,每3分鐘,喂數據的客戶端會將獲取到的耗時統計打印在一張十字座標圖中,這些圖又被保存在制定的Web站點中,並通過HTTP服務展示出來。在通過長時間不間斷的測試後,我得到了圖1。

圖1 插入Row的性能測試
圖1 插入Row的性能測試

圖1好似一條直線上,每隔一段時間就會泛起一個波浪,且兩個高峯之間必有一個較矮的波浪。高峯的間隔呈現出越來越大的趨勢,而較矮的波浪恰好處於兩高峯的中間位置。

解讀

爲了解釋,我對HDFS上HBase所在的主目錄下文件,以及被插入表格的region情況進行了實時監控,以期發現這些波浪上發生了什麼事情。

回溯到客戶端喂入數據的開始階段,創建表格,在HDFS上便被創建了一個與表格同名的目錄,該目錄下將出現第一個region,region中會以family名創建一個目錄,這個目錄下才存在記錄具體數據的文件。同時在該表表名目錄下,還會生成一個“compaction.dir”目錄,該目錄將在family名目錄下region文件超過指定數目時用於合併region。當第一個region目錄出現時,內存中最初被寫入的數據將被保存到該文件中,這個間隔是由選項“hbase.hregion.memstore.flush.size”決定的,默認是64MB,該region所在的Regionserver的內存中一旦有超過64MB的數據時,就將被寫入到region文件中。這個文件將不斷增殖,直到超過由“hbase.hregion.max.filesize”決定的文件大小(默認是256MB,此時加上內存刷入的數據,實際最大可能到256MB+64MB)時,該region將被執行split,立即被一切爲二,其過程是在該目錄下創建一個名爲“.splits”的目錄作爲標記,然後由Regionserver將文件信息讀取進來,分別寫入到兩個新的region目錄中,最後再將老的region刪除。這裏的標記目錄“.splits”可以避免在split過程中發生其他操作,起到類似於多線程安全的鎖功能。在新的region中,從老的region中切分出的數據獨立爲一個文件並不再接收新的數據(該文件大小超過了64MB,最大可達到(256+64)/2=160MB)),內存中新的數據將被保存到一個重新創建的文件中,該文件大小將爲64MB。內存每刷新一次,region所在的目錄下就將增加一個64MB的文件,直到總文件數超過由“hbase.hstore.compactionThreshold”指定的數量時(默認爲3),compaction過程就將被觸發了。在上述值爲3時,此時該region目錄下,實際文件數只有兩個,還有額外的一個正處於內存中將要被刷入到磁盤的過程中。Compaction過程是HBase的一個大動作。HBase不僅要將這些文件轉移到“compaction.dir”目錄進行壓縮,而且在壓縮後的文件超過256MB時,還必須立即進行split動作。這一系列行爲在HDFS上可謂是翻山倒海,影響頗大。待Compaction結束之後,後續的split依然會持續一小段時間,直到所有的region都被切割分配完畢,HBase纔會恢復平靜並等待下一次數據從內存寫入到HDFS。

圖2 再次的數據插入測試

圖2 再次的數據插入測試

理解了上述過程,就必然會對HBase的數據插入性能爲何是圖1所示的曲線的原因一目瞭然。與X軸幾乎平行的直線,表明數據正在被寫入HBase的Regionserver所在機器的內存中。而較低的波峯意味着Regionserver正在將內存寫入到HDFS上,較高的波峯意味着Regionserver不僅正在將內存刷入到HDFS,而且還在執行Compaction和Split兩種操作。如果調整“hbase.hstore.compactionThreshold”的值爲一個較大的數量,例如改成5,可以預見,在每兩個高峯之間必然會等間隔地出現三次較低的波峯,並可預見到,高峯的高度將遠超過上述值爲3時的高峯高度(因爲Compaction的工作更爲艱鉅)。由於region數量由少到多,而我們插入的Row的Rowkey是隨機的,因此每一個region中的數據都會均勻的增加,同一段時間插入的數據將被分佈到越來越多的region上,因此波峯之間的間隔時間也將會越來越長。

再次理解上述論述,我們可以推斷出HBase的數據插入性能實際上應該被分爲三種情況:直線狀態、低峯狀態和高峯狀態。在這三種情況下得到的性能數據纔是最終HBase數據插入性能的真實描述。那麼提供給用戶的數據該是採取哪一個呢?我認爲直線狀態由於所佔時間會較長,尤其在用戶寫入數據的速度也許並不是那麼快的情況下,所以這個狀態下得到的性能數據結果更應該提供給用戶。

圖3 圖1的數據分佈圖

圖3 圖1的數據分佈圖

再度分析

前面的HBase性能深度分析,提出了一個猜想,是關於調整“hbase.hstore.compaction-Threshold”值的假設。猜想的內容爲:如果改變該值,例如調整爲5,那麼耗時圖形會在每兩個高峯之間出現等間隔的三次較低的波峯,並且高峯將會更加突出,超過上述值較低時的波峯高度。

爲了證明這個猜想,我將“hbase.hstore.compactionThreshold”值調整爲5,並重新做了數據插入測試,一段時間後,得到如圖2所示的性能圖形(Y軸表示耗時,X軸爲插入次數,Sandy建議這裏的Y軸應該改爲插入速度,但是由於前次已經使用了耗時爲Y軸,因此改變Y軸顯示的工作只能放到下次測試中了)。

通過相比發現,圖1和圖2的Y軸比例尺是不同的,圖1中Y軸最大爲30秒,圖2中最大爲50秒。可見假設中聲稱低峯會在兩個高峯之間等間隔的出現3次的現象的確是成立的。當高峯出現第5次以後,可以從圖2看到代表耗時的點的高峯段已經達到了25秒以上,而對於前次來說,高峯段基本上處於20秒左右,由此可以認爲Compaction的壓力的確是增加了。現在換一個角度來分析這一情況。我爲圖1製作了一張數據分佈圖(圖3),與圖2進行比較(圖4)。

雖說第二次測試經歷的時間不如第一次,但是基於統計學的觀點,分佈圖的外形是不會受樣本容量大小影響的,因此圖3和圖4可以進行外觀上的比較。這兩張分佈圖都是典型的正態分佈圖,但又不是標準正態分佈,原因在於,波峯段的數據影響了正態分佈的標準性,表現之一在於右側的長尾,表現之二在於衆數所在位置右移,以至於左側凸顯了一個小波峯。

圖4 圖2的數據分佈圖

圖4 圖2的數據分佈圖

計算本次分佈圖與前次分佈圖中位於右側長尾部分的數據的標準差(計算公式:),我們可以得到前次右側標準差爲4.10390692438,而本次右側標準差爲7.12068861446,說明高峯段影響的數據右偏更爲嚴重了。

從外觀上表現在右側長尾在整圖比例尺中的寬度和高度要大於前次分佈圖中的右側長尾。這說明Compaction的壓力增大了。

推導到這裏,我發現右側標準差與Compaction的壓力之間是存在顯著關係的,今後對Compaction壓力增減的估算,貌似可以轉換爲對右側標準差的計算。壓力增加的比率是否等於標準差的比值呢?這裏先做一個標記,等後面有時間再仔細思考一下這個問題。現在假設中的說法“高峯將會更加突出,超過上述值較低時的波峯高度”,應該算是被證明了。

以上論證結束之後,按照慣例還是要提出一些假設和推斷。

HBase在已經發布的0.90.x版對Compaction和Split機制作了調整,將Split過程提到了Compaction之前,也就是說,當region目錄下,HFiles數目超過“hbase.hstore.compactionThreshold”指定值之後,Regionserver會首先計算一下Compaction之後的文件大小是否會超過“hbase.hregion.max.filesize”確定的Split上限大小,如果超過了,那麼HFiles首先被切分,然後纔會將切分好的文件轉移到新的region中Compaction。這樣將大大減小Compaction的壓力,由此可以推斷,HBase的性能調優必然與“hbase.hstore.compactionThreshold”和“hbase.hregion.max.filesize”這兩個值的大小息息相關。理論上,可以將某次設定了確定值的實驗中獲得的數據代入到一個特定公式中,上述兩值作爲該公式的自變量,其應變量,即性能數據,將可以輕鬆地計算出來。

是否真的如此,且待進一步的詳細測試。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章