由于Map/Reudce Job是运行在hadoop分布式环境中,所以给日常开发map/reduce的时候带来了很多不便,包括调试或者测试等。但是Apache下面一个开源的项目(MRUnit)可以对Map/Reduce进行单元测试,这样就可以使用单元测试用例来对Map/Reduce进行Debug,从而也可能通过丰富的测试用例来进行测试。可以在本地开发机上保证基本业务正确的前提下,再发布到hadoop分布式环境中解决一些分布式带来的问题。
MRUnit的具体使用官网中已经具体的使用说明。(MRUnit web site)
下面主要介绍一下Map/Reudce和MRUnit的最基本的原理,及对MRUnit中进行一些单独的展现来实现一些复杂的业务。
1. MAP
Map的基本原理(为了说明MRUnit在Map的基本原理),Map主要是读取原数据进行map操作,Hadoop Map/Reduce框架在map阶段调用org.apache.hadoop.mapreduce.Mapper.run方法,具体如下:
public void run(Context context) throws IOException, InterruptedException {
setup(context);
while (context.nextKeyValue()) {
map(context.getCurrentKey(), context.getCurrentValue(), context);
}
cleanup(context);
}
从上面的方法,可以看到在run中在开始和结果分别做了setup和cleanup操作,核心操作就是通过map context读取数据,并用读取到的key/value数据调用具体的map逻辑(通常map的逻辑是我们来实现),最终通过context.write把map的结果输出到中间结果(通常以文件形式)中提供reduce使用。
了解了map的基本原因之后,其实MRUnit主要做的就是mock一个map context,用于接受我们在单元测试中模拟数据,及对map的结果与测试用例中期望的结果进行比较。MapDriver通过 withInput和 withOutput来接受input和期望output,调用runTest来执行具体的map测试用例,如下:
mapDriver.withInput(new ChunkKey(), chunkWritable);
mapDriver.withOutput(new BytesWritable(SerializeUtil.serializeToBytes(multipleObject)), new BytesWritable(SerializeUtil.serializeToBytes(chunk)));
mapDriver.runTest();
runTest的具体实现如下,执行具体的run得到