我正在尝试使用 Hadoop 编写一个简单的 Map Reduce 程序,它将告诉我最容易患流感的月份。我正在使用可以在这里找到的谷歌流感趋势数据集 http://www.google.org/flutrends/data.txt .
我已经编写了 Mapper 和 reducer,如下所示
public class MaxFluPerMonthMapper extends Mapper<LongWritable, Text, IntWritable, IntWritable> {
private static final Log LOG =
LogFactory.getLog(MaxFluPerMonthMapper.class);
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
String row = value.toString();
LOG.debug("Received row " + row);
List<String> columns = Arrays.asList(row.split(","));
String date = columns.get(0);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
int month = 0;
try {
Calendar calendar = Calendar.getInstance();
calendar.setTime(sdf.parse(date));
month = calendar.get(Calendar.MONTH);
} catch (ParseException e) {
e.printStackTrace();
}
for (int i = 1; i < columns.size(); i++) {
String fluIndex = columns.get(i);
if (StringUtils.isNotBlank(fluIndex) && StringUtils.isNumeric(fluIndex)) {
LOG.info("Writing key " + month + " and value " + fluIndex);
context.write(new IntWritable(month), new IntWritable(Integer.valueOf(fluIndex)));
}
}
}
reducer
public class MaxFluPerMonthReducer extends Reducer<IntWritable, IntWritable, Text, IntWritable> {
private static final Log LOG =
LogFactory.getLog(MaxFluPerMonthReducer.class);
@Override
protected void reduce(IntWritable key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
LOG.info("Received key " + key.get());
int sum = 0;
for (IntWritable intWritable : values) {
sum += intWritable.get();
}
int month = key.get();
String monthString = new DateFormatSymbols().getMonths()[month];
context.write(new Text(monthString), new IntWritable(sum));
}
使用上面显示的这些 Mapper 和 Reducer,我得到以下输出
1 月 545419 2月528022 3 月 436348 4 月 336759 5 月 346482 六月 309795 七月 312966 八月 307346 九月 322359 十月 428346 十一月 461195 12 月 480078
我想要的只是一个输出给我 January 545419 我怎样才能做到这一点?通过将状态存储在 reducer 中还是有其他解决方案?或者我的映射器和缩减器对于我在这个数据集上提出的问题是错误的?
最佳答案
问题是 Reducer 不知道其他键(按设计)。可以设置另一个 Reducer 以在给定当前 reducer 的所有数据的情况下找到最大值。然而,这是过大的杀伤力,因为您知道您只有 12 条记录需要处理,并且设置另一个 Reducer 将比仅运行串行脚本有更多的开销。
我建议编写一些其他脚本来处理您的文本输出。
关于java - Hadoop - 如何获得谷歌流感趋势数据集中流感指数最高的月份?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6903206/