如何输出一个mapreduce作业作为另一个mapreduce作业的输入?

时间:2013-10-30 07:08:16

标签: java hadoop mapreduce

我是mapreduce和hadoop的新手。我读了mapreduce的例子和设计模式......

好的,我们可以说到这一点。我们正在开发一种软​​件,用于监控系统并定期捕获他们的CPU使用率,每5秒钟一次。我们在一系列时间段内绘制系统的使用图表,比如过去12小时的cpu使用情况,上周等等。我们正在使用oracle数据库。目前我们正准备转向hadoop。

我们讨论并提出了如下的mapreduce设计:

我们应该运行2个mapreduce工作

第一份工作:

收集所有系统的持久数据,并按系统ID分组(减少)它们 说输出为,

pc-1 : [ list of recorded cpu useges (in every 5 sec) ]

然后这将被提供给下一份工作

第二份工作:

输入是:[系统记录的cpu使用列表(每5秒)]

然后这个作业将这些数据分组并减少为输出格式,如:


last 12 hrs : 20%(average)
last 24 hrs : 28%(average)
last week   : 10%(average) ....

有可能吗?或者我们的想法是错的.. 请帮忙......

2 个答案:

答案 0 :(得分:1)

只需要一份工作。 Map任务将输出 - key:system-id,value:cpu-usage,date。

将为每个system-id输出Reduce任务,即每个请求时间范围的平均值。

Map输出值将是继承自Writeable的自定义类。

你没有提供一个确切的例子,但有类似的东西:

地图:

proctected void map(LongWritable key, Text value, Context context) {
    String[] fields = value.split("\t");
    output.set(Integer.parseInt(fields[1]));
    context.write(new Text(fields[0]), new Details(fields[1],fields[2]));
}

减少

DoubleWritable average = new DoubleWritable();
protected void reduce(Text key, Iterable<Details> values, Context context) {
    int[] sums = new int{0,0,0........};
    int[] counts = new int{0,0,0.........};
    int sum = 0;
    int count = 0;
    for(IntWritable value : values) {
      //for last 24 hours
        //if value is of last day........
        sums[0] += value.get();
        counts[0]++;
     //for last week
       //if value is of last week........
        sums[1] += value.get();
        counts[1]++;
     }
    //for last 24 hours
    average.set(sums[0] / (double) counts[0]);
    context.Write(key, average);
    //for last week        
    average.set(sums[1] / (double) counts[1]);
    context.Write(key, average);
    //............
}

答案 1 :(得分:0)

不需要两个单独的MR任务。

MR JOB:

MAP Phase Output - 输出{'system Id',[CPU使用列表]}

减速器阶段 - 计算平均值和其他信息。

如果您可以提供样本输入数据,则可以给出更详细的键值对描述。

为什么不使用类似Nagios的系统进行这些监控工作?