我正在开发一个map reduce应用程序,在该应用程序中,我必须获取月开始和月结束数据(不一定是月的第一个或最后一个日期,因为它们可以是假期或周六-周日)。因此,我提取月作为关键字,提取相应的日期作为值,以便按月汇总,并提取最大日期和最小日期。现在,基于这个日期,我需要使用文件的其他属性。所以我想把一个减速器的输出引导到另一个映射器中。第二个映射器也将文件作为输入,因此我可以比较日期并相应地处理数据。有什么办法我能做到吗??
在高层,实现这一点的一种方法是实现两个相继运行的MapReduce作业:
作业1获取输入数据集,并通过使用单个reducer将每个月的开始日期和结束日期的键值对输出到单个文件中。此输出文件将非常小。这可以类似于执行:
hadoop jar yourjob.jar YourFirstDriverClass /path/to/input /path/to/kvp/output
作业2采用相同的输入数据集,加上月份日期文件的路径,并输出处理结果。月份日期文件足够小,可以在每个映射器或reducer的setup()
调用中打开并加载到内存中。这可以类似于执行:
hadoop jar yourjob.jar YourSecondDriverClass /path/to/input /path/to/kvp/output /path/to/final/output
在您的驱动程序main()
中,您可以将对月份日期文件的引用传递给映射器和减速器,类似于:
getConf().set('month.dates.file', args[1]);
在映射器或还原器setup()
中,您可以从月份日期文件加载数据,类似于:
Configuration conf = context.getConfiguration();
Path path = new Path(conf.get('month.dates.file'));
FileSystem fs = FileSystem.get(conf);
BufferedReader br = new BufferedReader(new InputStreamReader(fs.open(path)));
String line = br.readLine();
while (line != null) {
// Read your month dates from line into a data structure, e.g. a Map
line = br.readLine();
}
将月份日期加载到mapper或reducer类的数据结构中后,您就可以为每次调用map()
或reduce()
访问它们,并相应地处理您的输入数据。
对于您正在尝试做的事情来说,这显然相当复杂,这是一个很好的例子,说明了为什么MapReduce抽象(如Apache Hive、Apache Pig和Apache Crunch)在实现代码少得多的作业时很受欢迎。