Hadoop測試常見問題和測試方法

testingbang發表於2019-07-29

隨著分散式計算技術的推廣,越來越多的大資料計算任務遷移到hadoop平臺上進行,模型類的hadoop應用也越來越多。經過這一段時間在hadoop上的測試專案,在此簡單分享下hadoop上專案測試的經驗。本文主要介紹專案測試過程中一些常見的現象以及問題的說明和一些常見的測試方法


一、測試常見問題

1、reduce輸出檔案,上傳檔案,下載檔案等操作的目的檔案的刪除。

【現象】程式第一次執行還是成功的,資料和程式都沒有修改,同樣的命令,執行第二次的時候,怎麼就失敗了呢?

【問題說明】由於hdfs檔案系統沒有覆蓋寫的特性。對於reduce的輸出,本地上傳檔案到hdfs上,下載hdfs檔案到本地等操作,當目的檔案已經存在,這些操作均會失敗。

【測試方法】對於具有上述操作的程式,一定要在程式執行前把對應的目的檔案刪除,特別是具有多輪迭代程式的臨時目錄需要清楚。

2、HADOOP_HOME環境變數的設定

【現象】在自己獨自使用的測試機上,利用hadoop命令新建了一個目錄,並利用hadoop dfs –ls path命令能夠檢視到該目錄存在,換到一個公用的機器上就找不到該目錄?

【問題說明】同一臺測試機器可能會有多個hadoop客戶端連線到多個不同的hadoop平臺。而當在shell命令列直接輸入hadoop命令時,系統預設是使用HADOOP_HOME下的hadoop客戶端。當HADOOP_HOME環境變數被別的使用者修改後,就會連線到別的hadoop平臺,當然就找不到所要的目錄:)。

【測試方法】當在程式中使用hadoop命令的時候,一定要指定hadoop命令的路徑,特別在rd提供的程式中,hadoop命令的路徑一定要可配。

3、Hadoop上程式輸入目錄的標準化

【現象】程式的輸入資料完全沒問題:檔案路徑和格式均正確,為什麼結果檔案都為空呢?

【問題說明】對於多路輸入(即多種格式的輸入檔案),rd進行設計程式的時候,常常會根據路徑名來進行檔案型別的判斷,進而進行不同的操作。此時,當外界輸入的路徑名沒有標準化(比如存在:./a/,/a//b,/a/./b),map階段透過比較傳遞的路徑引數和map環境變數獲取的當前處理檔案路徑來判斷當前處理的檔案塊來自哪個目錄,結果會判斷當前處理的檔案不來自任何輸入目錄,從而無法獲取輸入資料的型別。(當時針對這個問題排查很久,曾一度認為是hdfs的問題,最後透過檢視程式原始碼才發現該問題)

【測試方法】出現該情況,首先檢視該任務的監控頁面: Map input records的輸入是否為0,若是為0,則需檢查輸入資料地址正確性。Map output records是否為0. Map output records代表map的輸出,若是為0,那麼就是資料在map階段就被過濾掉,需要檢查輸入資料的格式正確性。然後檢視Reduce input records是否為0,若rduece的輸入為0,那輸出肯定就為0了。

4、Hadoop副本任務對程式結果的影響

【現象】在reduce中生成的本地檔案需要上傳到hdfs上。在上傳之前,為了避免目的檔案存在而導致上傳失敗,需要先進行刪除操作,然後再上傳。所有的reduce任務都正常結束,可是結果檔案偶爾會有缺失。而且是不能穩定復現。

【問題說明】hadoop執行map,red任務的時候,為了防止單個task執行緩慢,拖累整個任務的完成時間,會對一些task啟用備奮task,即多個task執行同一份資料,當一個task執行完成後,系統自動kill掉備份task。這樣可能導致備份task被kill前,正確的檔案上傳後,被備份任務刪除,導致最後結果檔案的缺失。而該現象還不是穩定復現。

【測試方法】對hdfs上的同一個檔案,目錄進行操作時,一定要注意並行操作的干擾。特別當在reduce中進行hdfs操作的時候,一定要考慮到副本的影響(該問題比較隱蔽)。解決方案是:1,禁止平臺生成副本任務(可以配置啟動引數達到目的)。2,在一個統一的單機進行此類操作。比如,現在單機處理好環境,然後啟動mapred任務。

5、Reduce資料分桶不均

【現象】透過檢視任務的監控頁面發現有的reduce執行時間很短,而有的reduce執行時間很長。

【問題說明】既然利用hadoop的任務,處理的資料一定是大資料量的。簡單的hash對映分桶可能導致分桶不均,從而多個reduce處理的資料量差別很大。

【測試方法】當前hadoop任務處理的資料很多都上T,若是在處理這麼大規模的資料,分桶不均,可能導致單個節點處理資料過大,導致效能降低,甚至可能導致記憶體超過閾值被平臺kill。因此在測試之前,一定要弄清楚,分桶的key和分桶函式是否會造成分桶不均。

6、worker資源分配的指定

【現象】每個task執行時間很短,叢集資源很充足,可是任務執行時間卻很長。

【問題說明】當處理的資料量很大時,任務會被分成很多的task,而當任務啟動時,叢集預設分配的worker會比較少,導致即使叢集資源空閒,執行該任務的worker數仍然很少,執行結束時間延長。

【測試方法】若是處理的資料很大,在任務啟動的時候,一定要指定資源引數,否則按照系統預設值,分配的work會很少(在hy叢集為50)。對於大資料量,該限制會大大降低效能。任務啟動的時候,可以透過監控頁面,檢視該任務執行的worker數。

7、單個worker記憶體限制

【現象】小資料量,測試透過,可是執行大資料,任務總是被平臺kill。

【問題說明】現在hadoop平臺對每個task執行時的記憶體進行了限制,預設是800M,當程式執行記憶體超過800M,平臺自動會kill該任務

【測試方法】針對該點測試有2種方法:1,在叢集執行大資料量,被平臺kill後,檢視日誌,確認是因為記憶體超出被平臺kill。2,在本地執行mapred程式,檢視程式記憶體佔用。若是在800M左右,上線就會有很大風險。

8、MPI程式對hadoop上檔案目錄的操作

【現象】在mpi節點上對同一目錄上的檔案進行操作,偶爾會失敗。

【問題說明】該問題同Hadoop副本任務對程式結果的影響 原因一樣,都多個節點對hadoop上同一個檔案的操作。只是一個是hadoop上,一個是mpi上。

【測試方法】多個地方對hdfs上的同一個檔案或者目錄進行操作。特別是同一個模組即在hadoop,又在mpi叢集上執行。不要在每個mpi節點同時對同一個hadoop目錄或者檔案進行修改操作。

9、對於map reduce的執行引數的設定

【現象】程式在本地就能執行成功,可是在hadoop上卻無法執行

【問題說明】有時候,map reduce的執行引數比較長,為了閱讀方便,rd可能會對程式引數進行折行,新增tab鍵排版,這樣反倒使hadoop上解析命令失敗。

【測試方法】對於map reduce的執行引數比較長的情況,可以督促rd用shell變數進行設定。然後在hadoop程式啟動引數用shell變數進行替換。即閱讀方便,又不會出錯。

10、Hadoop程式的結果使用的bistreaming的二進位制檔案結果

【現象】程式結果檔案是二進位制格式,可是下載到本地,按照詳細設計中描述的格式,解析格式總是錯誤。

【問題說明】當前流模式可以用streaming和bistreaming,當使用bistreaming時,生成的結果檔案是hadoop的 sequence file檔案格式,檔案格式中含有key length和value length資訊。在hadoop上使用該資料時,這個格式對使用者是透明的。下載到本地後,就不能直接使用了。

【測試方法】當任務的輸出outputformat=SequenceFileAsBinaryOutputFormat 時,可以使用hadoop dfs -copySeqFileToLocal –ignoreLen命令,把二進位制資料下載到本地,並去掉長度資訊,就和文件中寫的格式一致了。

11、Hadoop對於輸入檔案的切分

【現象】輸入檔案是基於session的query日誌行,session之間空行分割。當設定一個map的時候,程式結果正確,當設定多個map時,執行結果錯誤。

【問題說明】hadoop對於輸入檔案會以行為最小單元切分,因此,當輸入以空行為分割,有二次資料格式的時候,hadoop無法保證不把一個session切到兩個map task中。這樣就把一個session拆分為多個session了。

【測試方法】當程式實現邏輯依賴於比行粒度更大的單元時,需要設定map的切分大小比單個輸入檔案大,否則就回出現把輸入檔案切分成多個map輸入,導致切斷更大的輸入單元。


二、常用測試方法

1、跨叢集複製或者大資料量叢集內複製

在測試過程中,可能需要從摸個叢集或者某個目錄複製大量測試資料,若是先把資料複製到本地,在上傳到目的叢集,將會非常的耗時間,這時,可以考慮用distcp命令。

DistCp(分散式複製)是用於大規模叢集內部和叢集之間複製的工具。它使用Map/Reduce實現檔案分發,錯誤處理和恢復,以及報告生成。 它把檔案和目錄的列表作為map任務的輸入,每個任務會完成源列表中部分檔案的複製。

hadoop distcp hdfs://nn1:8020/foo/bar hdfs://nn2:8020/bar/foo這條命令會把nn1叢集的/foo/bar目錄下的所有檔案或目錄名展開並儲存到一個臨時檔案中,這些檔案內容的複製工作被分配給多個map任務, 然後每個TaskTracker分別執行從nn1到nn2的複製操作。注意DistCp使用絕對路徑進行操作。

由於distcp無法指定兩個使用者名稱和密碼,因此,複製的源和目的叢集的使用者名稱和密碼必須一致,且該使用者名稱密碼在源叢集具有讀許可權,在目的叢集具有寫許可權。

2、單機模擬分散式測試功能點

在測試部分功能點時或者記憶體不超過800M的效能時,可能會考慮到先用單機模擬分散式上執行進行測試:

cat input | mapper | sort | reducer > output

在用單機模擬分散式測試時,有以下注意點:

1)Streaming的輸入是按行劃分的文字,可以使用cat input即可;但是BiStreaming是“<key-length><key><value- length><value>”的格式,所以在輸入前要進行一定的處理;常用方法是:

cat input | ./ reader |./mapper |./ reducer >output

reader程式負責將檔案轉化為mapper程式能夠識別的keyLength, key, valueLength, value的二進位制格式。當輸入已經是sequencefile格式時,也不需要reader。

2)當Mapper或Reducer中使用到hadoop的環境變數時,單機模擬時,需要先修改這些環境變數或者在執行時設定這些環境變數的值。

3、分散式程式和單機程式結果的對比

在校驗分散式程式結果時,我們常常使用的方法是,實現一個單機版的程式,然後diff單機版和分散式版本的執行結果。

由於hadoop對於輸入檔案的切分,以及map後的reduce分桶。在和單機版做結果對比時,需要考慮到輸入行亂序對於結果的影響。若輸入行的亂序對結果的正確性沒有影響。那在做分散式的結果和本地單機模擬的結果diff時,一定要先sort,然後在diff。

4、總控指令碼的測試

分散式程式雖然以map-reduce程式為主體,但每一輪map-reduce任務都是在單機用指令碼進行任務提交和啟動,大多數專案都包含多輪map-reduce 任務。因此,各輪任務之間的排程協調和專案的系統執行就需要總控指令碼來完成。

在測試總控指令碼的時候,用-x引數執行,並把執行log重定向到輸出檔案。執行介紹後,即使結果正確,也需要看看執行指令碼的log,很可能發現一些意想不到的問題。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69942496/viewspace-2652129/,如需轉載,請註明出處,否則將追究法律責任。

相關文章