之前把HDFS-RAID遷移到Hadoop-2.2.0中,在公司的集羣內測試,用Java語言實現的EC算法超慢,下面是一些測試分析數據:
生成算法性能測試
測試目的:根據生成EC的三個流程,讀原始數據,計算EC校驗碼,寫校驗數據,我們要測試三個流程各自對總時間的佔比,這樣方便我們分析性能瓶頸在什麼地方。
預製條件:HDFS中存在測試文件。分析HDFS-RAID中的源代碼,在編碼器類Encoder的具體實現類ReedSolomonEncoder中的encodeStripe()方法中,存在如下邏輯:假定編碼策略爲RS(K,M),首先從流中讀入大小爲bufSize的K路數據,然後對這些讀入內存中的K路數據按字節進行EC運算,算出結果後,再把bufSize的M路數據寫出去HDFS。這三個小步驟計算完後,重新一個循環,直到把一個條帶內的塊數據計算完。對上面三個步驟的間隙我們分別記下時間戳,d0,d1,d2,d3。相互的差值剛好算出每部分的時長:
讀取原始數據時長 = t1 = d1 – d0
計算EC校驗碼時長 = t2 = d2 – d1
寫EC校驗數據時長 = t3 = d3 – d2
總時間 = t = d3 – d0
我們在程序中設置bufSize爲1M大小,程序運行時把上面的時間戳分別輸出,就可撲捉佔比信息。
測試結果:
|
耗時(毫秒) |
|||||||||
bufSize |
K |
M |
t1 |
% |
t2 |
% |
t3 |
% |
t |
% |
1M |
10 |
4 |
32 |
8% |
378 |
91% |
6 |
1% |
416 |
100% |
1M |
10 |
4 |
16 |
4% |
446 |
95% |
6 |
1% |
468 |
100% |
1M |
10 |
4 |
16 |
4% |
405 |
93% |
12 |
3% |
433 |
100% |
1M |
10 |
4 |
20 |
3% |
551 |
96% |
7 |
1% |
578 |
100% |
在記錄上面數據時,同時用top命令檢測機器上CPU的使用情況。當前機器配置了24個CPU核,檢測發現,在某個時刻,24核中總有一個核的CPU使用率維持在95%以上,而其他23核基本維持在空置情況。通過進程追蹤發現,促使CPU使用在95%以上的那個進程正是執行EC運算的程序。
結果分析:
通過對上表數據進行線性迴歸,粗略可以估算每個步驟的時間佔比:讀取原始數據佔比5%,計算EC數據佔比93%,寫EC校驗數據佔比2%。由此看出,在這個小串行的執行過程中,計算EC數據的整個性能的瓶頸。考慮計算EC數據的CPU使用情況,推知HDFS-RAID上基於Java原生態函數實現的EC算法,性能非常低,並且沒有把算法並行或併發化,沒有充分利用多核CPU的效力。(通過對源代碼的分析,佐證了這個推測。)
於是決定使用Jerasure替換HDFS-RAID中的計算模塊,Jerasure採用較爲舊的1.2版本,據說最新的2.0擁有更快的速度。
替換後,發現之前計算1M的數據大約在500ms左右,而替換後降爲100ms左右。通過執行計算時分析CPU使用情況發現,Jerasure依然沒有發揮多核的優勢,估計作者Plank依然沒有對EC進行並行化計算。
由於公司對這塊的計算速度有特殊的要求,打算繼續引入另一個可能更快的計算庫:ISA-L。到時對三者進行對比。