这听起来像一个简单的工作,但使用MapReduce似乎并不那么简单 .
我有N个文件,每个文件只有一行文本 . 我'd like the Mapper to output key value pairs like < filename, score >, in which '得分' is an integer calculated from the line of text. As a sidenote I am using the below snippet to do so (hope it'正确) .
FileSplit fileSplit = (FileSplit)reporter.getInputSplit();
String fileName = fileSplit.getPath().getName();
假设映射器正确地完成其工作,它应该输出N个键值对 . 现在的问题是 how should I program the Reducer to output the one key value pair with the maximum 'score' ?
据我所知,Reducer仅适用于共享相同密钥的键值对 . 由于这个场景中的输出都有不同的键,我猜测应该在Reduce步骤之前完成一些事情 . 或者也许应该完全省略Reduce步骤?
5 回答
您可以使用旧API中的setup()和cleanup()方法(configure()和close()方法) . 在reduce类中声明一个全局变量,它确定最大分数 . 对于每次调用reduce,您都会将输入值(score)与全局变量进行比较 .
在同一reduce任务中的所有reduce调用之前调用Setup()一次 . 在同一个reduce任务中的最后一次reduce调用之后调用Cleanup() . 因此,如果您有多个reducers,则会在每个reduce任务上单独调用Setup()和cleanup()方法 .
让我们假设
File1有10,123,23,233
File2有1,3,56,1234
File3有6,1,3435,678
以下是从所有输入文件中查找最大数量的方法 .
让我们先做一些随机抽样(比如说每N条记录) . 从File1 123和10,从File2 56和1,从File3 1和678 .
从随机抽样中选择最大数量,即678 .
将随机采样中的最大数量传递给映射器,并忽略输入数字减去随机采样中找到的最大数量,并在映射器中发出其他数字 . Mappers将忽略少于678的任何内容并发出678,1234和3435 .
将作业配置为使用1个reducer,并找到发送到reducer的所有数字的最大值 . 在这种情况下,reducer将收到678,1234和3435.并将计算最大数量为3435 .
对上述方法的一些观察
数据必须传递两次 .
在映射器和减速器之间传输的数据减少了 .
减速器处理的数据也减少了 .
更好的输入采样,更快地完成作业 .
具有与Reducer相似功能的组合器将进一步改善作业时间 .
您可以返回文件名和分数作为值,只返回任何常量作为映射器中的键
参见http://www.slideshare.net/josem.alvarez/map-reduceintro的幻灯片32和33
我用同样的方法得到了结果 . 唯一需要关注的是当您有多个字段时,需要单独创建fieldnamemin和fieldnamemax .
省略减速机!!使用配置将全局变量设置为分数和键,然后在映射器中访问它,通过使用全局变量作为最大分数和键的内存来进行简单的最大分数选择它应该很简单 . 我猜 .