hadoop单元测试方法--使用和增强MRUnit.doc_第1页
hadoop单元测试方法--使用和增强MRUnit.doc_第2页
hadoop单元测试方法--使用和增强MRUnit.doc_第3页
hadoop单元测试方法--使用和增强MRUnit.doc_第4页
hadoop单元测试方法--使用和增强MRUnit.doc_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

hadoop单元测试方法-使用和增强MRUnit无花1前言hadoop的mapreduce提交到集群环境中出问题的定位是比较麻烦的,有时需要一遍遍的修改代码和打出日志来排查一个很小的问题,如果数据量大的话调试起来相当耗时间。因此有必要使用良好的单元测试手段来尽早的消除明显的bug(当然仅有单元测试是不够的,毕竟跟集群的运行环境还是不一样的)。然而做mapreduce的单元测试会有一些障碍,比如Map和Reduce一些参数对象是在运行时由hadoop框架传入的,例如OutputCollector、Reporter、InputSplit等。这就需要有Mock手段。最初写mapreduce单元测试的时候自己写了几个简单的Mock也基本能满足需要,后来发现MRUnit比我写的要好用所以研究了一下就采用了。MRUnit是专门为hadoop mapreduce写的单元测试框架,API简洁明了,简单实用。但也有一些薄弱的地方,比如不支持MultipleOutputs(很多情况下我们会用MultipleOutputs作为多文件输出,后面将介绍如何增强MRUnit使之支持MultipleOutputs)。2 MRUnitMRUnit针对不同测试对象分别使用以下几种Driver:l MapDriver,针对单独的Map测试。l ReduceDriver,针对单独的Reduce测试。l MapReduceDriver,将Map和Reduce连贯起来测试。l PipelineMapReduceDriver,将多个Map-Reduce pair贯串测试。MapDriver单独测试Map的例子,假设我们要计算一个卖家的平均发货速度。Map将搜集每一次发货的时间间隔。针对Map的测试,/这是被测试的Map private Map mapper; private MapDriver mapDriver; Before public void setUp() mapper = new Map(); mapDriver = new MapDriver(); Test public void testMap_timeFormat2() String sellerId = 444; /模拟输入一行(withInput),假设从这行数据中我们可以获得卖家(sellerId)/某一次时间间隔为10小时./我们期望它输出sellerId为key,value为代表1次10小时的TimeInfo对象。/(withOutput)/如果输入数据经过Map计算后为期望的结果,那么测试通过。Text mapInputValue = new Text(); mapDriver.withMapper(mapper).withInput(null, mapInputValue).withOutput(new Text(sellerId), new TimeInfo(1, 10).runTest(); ReduceDriver针对Reduce的单独测试,还是这个例子。Reduce为根据Map或Combiner输出的n次时间间隔的总和来计算平均时间。 private Reduce reducer;Before public void setUp() reducer = new Reduce(); reduceDriver = new ReduceDriver(reducer); Test public void testReduce () List values = new ArrayList(); values.add(new TimeInfo(1, 3);/一次3小时 values.add(new TimeInfo(2, 5);/两次总共5小时 values.add(new TimeInfo(3, 7);/三次总共7小时/values作为444这个卖家的reduce输入,/期望计算出平均为2小时 reduceDriver.withReducer(reducer).withInput(new Text(444), values).withOutput(new Text(444),new LongWritable(2).runTest(); MapReduceDriver以下为Map和Reduce联合测试的例子, private MapReduceDriver mrDriver; private Map mapper; private Reduce reducer;Before public void setUp() mapper = new Map(); reducer = new Reduce(); mrDriver = new MapReduceDriver(mapper, reducer); Test public void testMapReduce_3record_1user() Text mapInputValue1 = new Text();Text mapInputValue2 = new Text();Text mapInputValue3 = new Text();/我们期望从以上三条Map输入计算后,/从reduce输出得到444这个卖家的平均时间为2小时. mrDriver.withInput(null, mapInputValue1).withInput(null, mapInputValue2).withInput(null, mapInputValue3).withOutput(new Text(444),new LongWritable(2).runTest();3 增强MRUnit下面介绍为MRUnit框架增加了支持MultipleOutputs、从文件加载数据集和自动装配等几个特性,使它更加便于使用。如何支持MultipleOutputs然而很多场景下我们需要使用MultipleOutputs作为reduce的多文件输出,MRUnit缺少支持。分析源码后为MRUnit增强扩展了两个Driver:ReduceMultipleOutputsDriver和MapReduceMultipleOutputDriver来支持MultipleOutputs。ReduceMultipleOutputsDriverReduceMultipleOutputsDriver是ReduceDriver的增强版本,假设前面例子中的Reduce使用了MultipleOutputs作为输出,那么Reduce的测试将出现错误。使用ReduceMultipleOutputsDriver改造上面的测试用例(注意粗体部分),private Reduce reducer;Before public void setUp() reducer = new Reduce();/注意这里ReduceDriver改为使用ReduceMultipleOutputsDriver reduceDriver = new ReduceMultipleOutputsDriver(reducer); Test public void testReduce () List values = new ArrayList(); values.add(new TimeInfo(1, 3);/一次3小时 values.add(new TimeInfo(2, 5);/两次总共5小时 values.add(new TimeInfo(3, 7);/三次总共7小时/values作为444这个卖家的reduce输入,/期望计算出平均为2小时 reduceDriver.withReducer(reducer).withInput(new Text(444), values)/Note/假设使用id(444)%8的方式来分文件/表示期望somePrefix+444%8这个collector将搜集到数据xxx. withMutiOutput (somePrefix+444%8,new Text(444),new LongWritable(2).runTest(); MapReduceMultipleOutputDriver跟ReduceMultipleOutputsDriver类似,MapReduceMultipleOutputDriver用来支持使用了MultipleOutputs的Map-Reduce联合测试。MapReduceDriver一节中的例子将改为,private MapReduceDriver mrDriver; private Map mapper; private Reduce reducer;Before public void setUp() mapper = new Map(); reducer = new Reduce();/改为使用ReduceMultipleOutputsDriver mrDriver = new ReduceMultipleOutputsDriver(mapper, reducer); Test public void testMapReduce_3record_1user() Text mapInputValue1 = new Text();Text mapInputValue2 = new Text();Text mapInputValue3 = new Text();/我们期望从以上三条Map输入计算后,/从reduce输出得到444这个卖家的平均时间为2小时. mrDriver.withInput(null, mapInputValue1).withInput(null, mapInputValue2).withInput(null, mapInputValue3)/表示期望somePrefix+444%8这个collector将搜集到数据xxx. withMutiOutput (somePrefix+444%8,new Text(444),new LongWritable(2).runTest();如何从文件加载输入从以上例子看到使用MRUnit需要重复写很多类似的代码,并且需要把输入数据写在代码中,显得不是很优雅,如果能从文件加载数据则会方便很多。因此通过使用annotation和扩展JUnit runner,增强了MRUnit来解决这个问题。改造上面的例子,使得map的输入自动从文件加载,并且消除大量使用MRUnit框架API的代码。RunWith(MRUnitJunit4TestClassRunner.class)public class XXXMRUseAnnotationTest /表示自动初始化mrDriver,并加载数据(如果需要)MapInputSet MapReduce(mapper = Map.class, reducer = Reduce.cla

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论