我是hadoop世界的新手,并且正在努力完成一项简单的任务而没有找到方法。
我们有一种情况,其中有不同的客户呼叫不同的 人(与不同的移动运营商)。每个电话详细信息都有通话开始时间 日期,与日期的呼叫结束时间,已拨打电话的各种运营商名称。
我们有以下格式的输入文件:
客户电话号码|使用日期开始通话时间|结束与日期的通话时间|
已经拨打电话的各种移动运营商
例如输入文件是这样的:
9898765467| 03:14 12/10/2013 | 03:40 12/10/2013 | airtel
9898765467| 06:20 12/10/2013 | 07:05 12/10/2013 | vodaphone
9899875321| 08:14 13/10/2013 | 08:40 13/10/2013 | idea
9899875321| 04:15 13/10/2013 | 04:50 13/10/2013 | reliance
9899875321| 09:14 13/10/2013 | 09:30 13/10/2013 | idea
9898765467| 10:20 12/10/2013 | 10:55 12/10/2013 | vodaphone
现在我们想知道每个日期根据哪个手机号码调用哪个手机号码 运营商和通话时间有多长?
就像在给定示例中的9898765467手机号码一样,拨打vodaphone运营商两次
12/10/2013
总通话时间为((7:05-6:20)+(10:55-10:20))=45 + 35 = 80 mins
因此手机号码9898765467的输出应该是:
Mobile number | Date | Operator name | Talk Time
9898765467 | 12/10/2013 | vodaphone | 80 mins
So final output file for all mobile numbers should be like:
9898765467 | 12/10/2013 | vodaphone | 80 mins
9898765467 | 12/10/2013 | airtel | 26 mins
9899875321 | 13/10/2013 | idea | 42 mins
9899875321 | 13/10/2013 | reliance | 35 mins
有人可以建议或提供地图缩减代码来完成这项任务吗?
答案 0 :(得分:3)
首先,您需要为作业(Map-Reduce)确定Keys
和Values
。
在这种情况下,
您需要为每个mobileNumber-date-operator
组合生成持续时间。
因此, 每行的映射器输出都是,(键 - 上面的组合,值 - 该行的持续时间)。
你的缩减器需要summation
持续时间for all
这样的唯一键(组合)。
请通过示例来了解逻辑。
由于我主要集中在逻辑部分,您可能需要根据业务需要修改string/date formatting
和line splits/tokens
。
package stackoverflow.examples;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class CallStatsJob {
public static class CallStatsMapper extends
Mapper<Object, Text, Text, LongWritable> {
private LongWritable duration;
private Text key = new Text();
private String mobileNumber, startTime, endTime, operator;
public void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
String[] words = value.toString().split(" \\| ");
mobileNumber = words[0];
startTime = words[1];
endTime = words[2];
operator = words[3];
// for debugging
// System.out.println(mobileNumber);
// System.out.println(startTime);
// System.out.println(endTime);
// System.out.println(operator);
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm dd/M/yyyy");
// String dateInString = "03:40 12/10/2013";
Date stDate, enDate;
try {
stDate = sdf.parse(startTime);
enDate = sdf.parse(endTime);
Long diff = enDate.getTime() - stDate.getTime();
Long diffMinutes = diff / (60 * 1000);
this.key = new Text(mobileNumber+"-"+stDate.getDate()+"-"+operator);
duration = new LongWritable(diffMinutes);
context.write(this.key, duration);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
public static class CallStatsReducer extends
Reducer<Text, LongWritable, Text, LongWritable> {
public void reduce(Text key, Iterable<LongWritable> values,
Context context) throws IOException, InterruptedException {
Long sum = 0L;
for (LongWritable val : values) {
sum = sum + val.get();
}
context.write(key, new LongWritable(sum));
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = new Job(conf, "Caller Statistics");
job.setJarByClass(CallStatsJob.class);
job.setMapperClass(CallStatsMapper.class);
job.setReducerClass(CallStatsReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true)?0:1);
}
}
映射器输出:(如果设置0减速器,您将能够看到此输出)
9898765467-12-airtel 26
9898765467-12-vodaphone 45
9899875321-13-idea 26
9899875321-13-reliance 35
9899875321-13-idea 16
9898765467-12-vodaphone 35
减速机输出:(上述作业的一般输出)
9898765467-12-airtel 26
9898765467-12-vodaphone 80
9899875321-13-idea 42
9899875321-13-reliance 35
我相信这个例子可以为您提供解决方案以及进一步了解的理解。
答案 1 :(得分:0)
使用WordCount Program
作为参考。
将地图键设为NUMBER |日期| OPERATOR
将地图值作为持续时间制作。 (你可以找到开始和结束时间之间的差异)
所以映射器在那里结束。
在reducer中,只需总结每个键的持续时间列表。
从减速器发出结果。
答案 2 :(得分:0)
您可以使用没有地图缩减代码的配置单元来实现此目的。 在此文件上创建一个配置单元表。
创建外部表callrecords(移动字符串,starttime字符串,endtime字符串,运算符字符串)以'|'结尾的行格式分隔字段以“\ n”位置'tblproperties(“skip.header.line.count”=“1”)终止的行;
通过计算开始和结束时间之间的差异,在表格上创建一个视图create view as select。 This会帮助你计算差异。