使用MRUnit測試Hadoop程序

這篇文章將略微繞開使用MapReduce實現數據密集型處理中的模式,以討論同樣重要的測試。 湯姆?惠勒 ( Tom Wheeler)在紐約2012年Strata / Hadoop World會議上參加的一次演講給了我部分啟發。 處理大型數據集時,想到的并不是單元測試。 但是,當考慮到無論集群有多大或有多少數據時,都將相同的代碼推送到所有節點以運行MapReduce作業,因此Hadoop映射器和化簡器非常適合進行單元測試。 但是,對框架進行Hadoop的單元測試并不容易。 幸運的是,有一個使Hadoop測試相當容易的庫– MRUnit 。 MRUnit基于JUnit,并允許對映射器,化簡器進行單元測試以及對映射器進行一些有限的集成測試-歸化器與組合器,自定義計數器和分區器之間的交互。 在撰寫本文時,我們正在使用MRUnit的最新版本0.9.0。 所有測試的代碼均來自上一則有關使用本地聚合計算平均值的文章 。

設定

要開始使用,請從此處下載MRUnit。 解壓縮tar文件后,將cd插入mrunit-0.9.0-incubating / lib目錄。 在其中,您應該看到以下內容:

  1. mrunit-0.9.0-incubating-hadoop1.jar
  2. mrunit-0.9.0-incubating-hadoop2.jar

我敢肯定,mrunit-0.9.0-incubating-hadoop1.jar用于Hadoop的MapReduce版本1,而mrunit-0.9.0-incubating-hadoop2.jar用于處理Hadoop的新版本的MapReduce。 對于本文以及其他所有后續文章,我們將使用Cloudera CDH4.1.1發行版中的hadoop-2.0版本,因此我們需要mrunit-0.9.0-incubating-hadoop2.jar文件。 我在Intellij中將MRUnit,JUnit和Mockito添加為庫(JUnit和Mockito與MRUnit jar文件位于同一目錄中)。 現在我們已經建立了依賴關系,讓我們開始測試。

測試映射器

設置測試映射器非常簡單,最好先查看一些代碼來說明。 我們將使用上一篇文章中的映射器內合并示例:

@Test
public void testCombiningMapper() throws Exception {new MapDriver<LongWritable,Text,Text,TemperatureAveragingPair>().withMapper(new AverageTemperatureCombiningMapper()).withInput(new LongWritable(4),new Text(temps[3])).withOutput(new Text('190101'),new TemperatureAveragingPair(-61,1)).runTest();}

注意流利的api樣式,這增加了創建測試的便利性。 要編寫測試,您將:

  1. 實例化完全與被測映射器參數化的MapDriver類的實例。
  2. 在withMapper調用中添加要測試的Mapper實例。
  3. 在withInput調用中,輸入您的鍵和輸入值,在這種情況下,一個LongWritable具有任意值和一個Text對象,該對象包含來自NCDC天氣數據集的行,該數據集包含在名為“ temps”的字符串數組中,該數組早些時候在其中建立。測試(此處不會顯示,因為它會從演示文稿中刪除)。
  4. 在withOutput調用中指定期望的輸出,這里我們期望一個Text對象的值為“ 190101”,一個TemperatureAveragingPair對象的值為-61(溫度)和1(計數)。
  5. 最后一個調用runTest將指定的輸入值輸入到映射器中,并將實際輸出與“ withOutput”方法中設置的預期輸出進行比較。

要注意的一件事是MapDriver每次測試僅允許一個輸入和輸出。 您可以根據需要多次調用withInput和withOutput,但是MapDriver會用新值覆蓋現有值,因此您將只能在任何時候使用一個輸入/輸出進行測試。 為了指定多個輸入,我們將使用MapReduceDriver,稍后將介紹幾節,但接下來將測試reducer。

測試減速器

測試減速器遵循與映射器測試相同的模式。 再次,讓我們看一個代碼示例:

@Test
public void testReducerCold(){List<TemperatureAveragingPair> pairList = new ArrayList<TemperatureAveragingPair>();pairList.add(new TemperatureAveragingPair(-78,1));pairList.add(new TemperatureAveragingPair(-84,1));pairList.add(new TemperatureAveragingPair(-28,1));pairList.add(new TemperatureAveragingPair(-56,1));new ReduceDriver<Text,TemperatureAveragingPair,Text,IntWritable>().withReducer(new AverageTemperatureReducer()).withInput(new Text('190101'), pairList).withOutput(new Text('190101'),new IntWritable(-61)).runTest();}
  1. 該測試首先創建一個TemperatureAveragingPair對象列表,用作減速器的輸入。
  2. 實例化了ReducerDriver,并且與MapperDriver一樣,對它的參數設置也與被測試的reducer完全相同。
  3. 接下來,我們要在withReducer調用中傳入要測試的reducer實例。
  4. 在withInput調用中,我們傳入鍵“ 190101”和在測試開始時創建的pairList對象。
  5. 接下來,我們指定我們期望減速器發出的輸出,相同的鍵“ 190101”和一個IntWritable,它表示列表中的溫度平均值。
  6. 最后調用runTest,它將給我們的減速器提供指定的輸入,并將減速器的輸出與期望輸出進行比較。

ReducerDriver具有與MapperDriver相同的限制,即不接受多個輸入/輸出對。 到目前為止,我們已經單獨測試了Mapper和Reducer,但我們也想在集成測試中一起測試它們。 可以通過使用MapReduceDriver類完成集成測試。 MapReduceDriver還是用于測試組合器,自定義計數器或自定義分區程序使用情況的類。

整合測試

為了測試您的mapper和reducer一起工作,MRUnit提供了MapReduceDriver類。 正如您現在所期望的,MapReduceDriver類有兩個主要區別。 首先,參數化映射器的輸入和輸出類型以及化簡器的輸入和輸出類型。 由于映射器輸出類型需要與化簡器輸入類型匹配,因此最終需要3對參數化類型。 其次,您可以提供多個輸入并指定多個預期輸出。 這是我們的示例代碼:

@Test
public void testMapReduce(){new MapReduceDriver<LongWritable,Text,Text,TemperatureAveragingPair,Text,IntWritable>().withMapper(new AverageTemperatureMapper()).withInput(new LongWritable(1),new Text(temps[0])).withInput(new LongWritable(2),new Text(temps[1])).withInput(new LongWritable(3),new Text(temps[2])).withInput(new LongWritable(4),new Text(temps[3])).withInput(new LongWritable(5),new Text(temps[6])).withInput(new LongWritable(6),new Text(temps[7])).withInput(new LongWritable(7),new Text(temps[8])).withInput(new LongWritable(8),new Text(temps[9])).withCombiner(new AverageTemperatureCombiner()).withReducer(new AverageTemperatureReducer()).withOutput(new Text('190101'),new IntWritable(-22)).withOutput(new Text('190102'),new IntWritable(-40)).runTest();}

從上面的示例中可以看到,設置與MapDriver和ReduceDriver類相同。 您傳入了映射器,reducer和(可選)組合器的實例進行測試。 MapReduceDriver允許我們傳遞具有不同鍵的多個輸入。 此處的“溫度”數組與Mapper樣本中引用的數組相同,并包含NCDC天氣數據集中的幾行內容,這些樣本行中的關鍵字為1901年1月和2月,分別表示為“ 190101”和“ 190102“。 該測試是成功的,因此我們對映射器和化簡器一起工作的正確性有了更多的信心。

結論

希望我們已經證明了MRUnit對于測試Hadoop程序有多么有用。 我想用我自己的一些觀點來總結這篇文章。 盡管MRUnit使映射器和化簡器代碼的單元測試變得容易,但是這里介紹的映射器和化簡器示例相當簡單。 如果您的映射和/或精簡代碼開始變得更加復雜,則最好將代碼與Hadoop框架解耦,然后單獨測試新類。 另外,與MapReduceDriver類一樣,它用于集成測試也非常有用,很容易達到不再測試代碼,而已經測試Hadoop框架本身的地步。 我提出了自己打算繼續使用的測試策略:

  1. 單元測試映射/減少代碼。
  2. 可能使用MapReduceDriver類編寫一個集成測試。
  3. 作為健全性檢查,請在單節點安裝(在我的筆記本電腦上)上運行MapReduce作業,以確保其在Hadoop框架上運行。
  4. 然后在我的案例中,使用Apache Whirr在EC2的測試集群上運行我的代碼。

討論如何在筆記本電腦(OSX Lion)上設置單節點安裝以及如何使用Whirr在EC2上建立群集將使這篇文章過長,因此我將在下一篇文章中介紹這些主題。 謝謝你的時間。

資源資源

  • Jimmy Lin和Chris Dyer 使用MapReduce進行的數據密集型處理
  • Hadoop: Tom White 的權威指南
  • 來自博客的源代碼
  • Hadoop API
  • MRUnit用于單元測試Apache Hadoop映射減少工作
  • Gutenberg項目提供了大量純文本格式的書籍,非常適合在本地測試Hadoop作業。


參考:來自我們的JCG合作伙伴 Bill Bejeck的《 Random Thoughts On Coding》博客中的MRUnit測試Hadoop程序 。

翻譯自: https://www.javacodegeeks.com/2012/11/testing-hadoop-programs-with-mrunit.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371032.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371032.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371032.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

android之 TextWatcher的監聽

以前用過android.text.TextWatcher來監聽文本發生變化&#xff0c;但沒有仔細去想它&#xff0c;今天興致來了就發個瘋來玩玩吧&#xff01; 有點擔心自己理解錯&#xff0c;所以還是先把英文API解釋給大家看看 1、什么情況下使用了&#xff1f; When an object of a type is a…

php 秒殺并發怎么做,PHP實現高并發下的秒殺功能–Laravel

namespace App\Http\Controllers\SecKill;use App\Http\Controllers\Controller;use Exception;use Illuminate\Support\Facades\DB;use Illuminate\Support\Facades\Redis;class SecKillController extends Controller{/*** 往redis的隊列中添加庫存(用於測試的數據)**/public…

蘋果mp3軟件_優秀的Apple音樂轉換器,將任何iTunes M4P,AAX,AA轉換為MP3

Macsome iTunes Converter是一款優秀的音頻轉換工具&#xff0c;這款音頻轉換軟件能夠幫助大家快速進行音頻格式轉換&#xff0c;使得您可以自由的播放和分享自己喜愛的音頻文件。同時這款軟件與大多數音頻轉換軟件一樣&#xff0c;將受到保護DRM的Apple音樂轉換轉換成MP3, AAC…

Vuejs開發環境搭建及熱更新

一、安裝NPM 1.1最新穩定版本&#xff1a; npm install vue 二、命令行工具安裝 國內速度慢&#xff0c;使用淘寶鏡像&#xff1a; npm install -g cnpm --registryhttps://registry.npm.taobao.org 注意&#xff1a;以后使用npm的地方就替換成cnpm 1、全局安裝vue-vli ? …

線索二叉樹的C語言實現

#include "string.h"#include "stdio.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h" #define OK 1#define ERROR 0#define TRUE 1#define FALSE 0 #define MAXSIZE 100 /* 存儲空…

發送帶有接縫的活動邀請

這些天來&#xff0c;我的一位同事在使用帶有接縫&#xff08;2.x版&#xff09;的郵件模板發送事件邀請時遇到了問題。 從根本上講&#xff0c;這不是一個艱巨的任務&#xff0c;因此我將簡要說明使用接縫郵件模板發送事件邀請需要做什么。 發送郵件邀請時&#xff0c;您需要發…

Oracle內存管理(之二)

Oracle內存管理&#xff08;之二&#xff09; 【深入解析--eygle】 學習筆記 1.2.2 UGA和CGA UGA&#xff08;用戶全局區&#xff09;由用戶會話數據、游標狀態和索引區組成。在共享server模式下&#xff0c;一個共享服務進程被多個用戶進程共享&#xff0c;此時UGA是Shared Po…

matlab抓取股票數據,Matlab經過sina web接口獲取個數即時股票數據函數實現代碼

Matlab通過sina web接口獲取個數即時股票數據函數實現代碼代碼如下&#xff1a;function stockinfo queryprice(stocktype, stockid)%stocktype 股票類型&#xff1a;sh和sz%stockid 股票編碼&#xff1a;url sprintf(http://hq.sinajs.cn/list%s%d, stocktype, stockid);[so…

虛幻4毛發系統_虛幻引擎復活!蘋果與Epic對決,有哪些游戲險些中槍?

最近&#xff0c;蘋果和Epic的官司鬧得沸沸揚揚。隨著Epic旗下熱門手游《堡壘之夜》遭蘋果火速下架&#xff0c;兩大巨頭之間的沖突愈演愈烈。蘋果似乎并不滿足于此&#xff0c;由于Epic公開違反自家規定&#xff0c;蘋果計劃進一步封禁Epic維護虛幻引擎的開發者賬戶&#xff0…

史上最全的HTML和CSS標簽常用命名規則

文件夾主要建立以下文件夾&#xff1a;  1、Images 存放一些網站常用的圖片&#xff1b;  2、Css 存放一些CSS文件&#xff1b;  3、Flash 存放一些Flash文件&#xff1b;  4、PSD 存放一些PSD源文件&#xff1b;  5、Temp 存放所有臨時圖片和其它文件&#xff1b; …

01-JAVA語言基礎

1.設計思想&#xff1a; 先以字符串的形式輸入兩個數字&#xff0c;然后將他們轉化為int類型&#xff0c;再對兩數進行相加&#xff0c;最后輸出結果。 2.程序流程圖&#xff1a; 3.源程序代碼&#xff1a; import java.util.Scanner;public class Addition2 {public static vo…

與JodaTime的DateTime和Google Guava的供應商嘲笑

介紹 如果您是經驗豐富的單元測試人員&#xff0c;那么當您看到任何與時間 &#xff0c; 并發性 &#xff0c; 隨機性 &#xff0c; 持久性和磁盤I / O協同工作的代碼時&#xff0c;您就會學會做筆記。 原因是測試可能非常脆弱&#xff0c;有時完全無法正確測試。 這篇文章將展…

棧實現 C語言

最近上來寫了一下棧&#xff0c;理解數據結構的棧。 頭文件&#xff1a;stack.h 初始化棧結構與函數定義&#xff1a; #include<stdlib.h> #include <stdio.h> #include<memory.h> #define N 100struct stack {int data[N];int top;//標識棧頂 }; typedef s…

php簽名墻,肺功能檢查質量控制網

2017年12月2日&#xff0c;由中華醫學會呼吸病學分會/兒科分會、國家呼吸系統疾病臨床醫學研究中心、國家呼吸疾病醫療質量控制中心、中國肺功能聯盟、中國兒童肺功能協作組主辦&#xff0c;浙江省中醫院承辦的"2017年中國肺功能檢查規范化培訓及應用推廣學習班暨肺功能檢…

餐飲水單打印軟件_開發一款餐飲手機app系統軟件什么價格?有哪些方面需要考慮?...

開發一款餐飲手機app系統軟件什么價格&#xff1f;有哪些方面需要考慮&#xff1f;近年來&#xff0c;餐飲類的APP如雨后春筍般快速增長&#xff0c;無論是上檔次的酒店&#xff0c;還是各大餐廳&#xff0c;都有各自的專屬APP。餐飲APP的開發能讓大型酒店/餐廳獲得更多盈利、銷…

html5中如何去掉input type date默認

html5中如何去掉input type date默認樣式 2.對日期時間控件的樣式進行修改目前WebKit下有如下9個偽元素可以改變日期控件的UI&#xff1a;::-webkit-datetime-edit – 控制編輯區域的::-webkit-datetime-edit-fields-wrapper – 控制年月日這個區域的::-webkit-datetime-edit-…

Spring-framework應用程序啟動loadtime源碼分析筆記(二)——@Transactional

Transactional標識類或方法&#xff0c;使方法被執行時使用事務方式執行&#xff0c;這里只討論PROXY方法增強方法。使用EnableTransactionManagement&#xff0c;默認modelAdviceMode.PROXY&#xff0c;通過Import(TransactionManagementConfigurationSelector.class)來判斷在…

具有Spring的簡單工作流引擎

幾個月前&#xff0c;在處理一個公司項目時&#xff0c;我們需要開發REST服務&#xff0c;該服務用于根據客戶端應用程序發送的數據發送電子郵件。 在開發此服務期間&#xff0c;我們決定創建簡單的工作流引擎&#xff0c;該引擎將為發送電子郵件收費&#xff0c;但該引擎也可用…

php put 參數,php – 如何在Guzzle 5中發送PUT請求的參數?

根據the manual,The body option is used to control the body of an entity enclosingrequest (e.g., PUT, POST, PATCH).記錄的put’ing方法是&#xff1a;$client new GuzzleHttp\Client();$client->put(http://httpbin.org, [headers > [X-Foo > Bar],body > …

TypeScript學習筆記歸納(持續更新ing)

文章目錄 前言 二、TypeScript的優勢體現在哪里&#xff1f; 1、執行時間上的區別 2、基礎數據類型區別 3、TS優勢 三、TypeScript的關鍵特性 四、TypeScript的類型系統 1、什么是類型注釋&#xff1f; 2、類型系統核心 - 常用類型 1&#xff09; 基本類型&#xff0…