赞
踩
一:案例需求
现假设有数据文件num.txt,现要求使用MapReduce技术提取上述文本中最大的5个数据,并最终将结果汇总到一个文件中。先设置MapReduce分区为1,即ReduceTask个数一定只有一个。我们需要提取TopN,即全局的前N条数据,不管中间有几个Map、Reduce,最终只能有一个用来汇总数据。在Map阶段,使用TreeMap数据结构保存TopN的数据,TreeMap默认会根据其键的自然顺序进行排序,也可根据创建映射时提供的 Comparator进行排序,其firstKey()方法用于返回当前集合最小值的键。在Reduce阶段,将Map阶段输出数据进行汇总,选出其中的TopN数据,即可满足需求。这里需要注意的是,TreeMap默认采取正序排列,需求是提取5个最大的数据,因此要重写Comparator类的排序方法进行倒序排序。
二:案例实施
第一步:下载idea以及需要的工具,可以参考Centos7安装并使用IntelliJ IDEA这篇文章。注意下载Linux版本。
第二步:下载并安装完idea,先启动Hadoop,使用命令:start-all.sh 启动完成后使用jps查看Hadoop集群是否启动成功。启动Hadoop成功后启动idea。
第三步:在虚拟机上创建文本文件
向num.txt文件添加如下内容:
10 3 8 7 6 5 1 2 9 4
11 12 17 14 15 20
19 18 13 16
使用IntelliJ开发工具创建Maven项目TopN,并且新建net.hw.mr包,在该路径下编写自定义Mapper类TopNMapper,主要用于将文件中的每行数据进行切割提取,并把数据保存到TreeMap中,判断TreeMap是否大于5,如果大于5就需要移除最小的数据。TreeMap保存了当前文件最大5条数据后,再输出到Reduce阶段。
(1)创建Maven项目:TopN
1.在idea左上角新建项目。包名:net.army.mr配置好如下图,单击【Create】按钮
(1)在resources目录里创建log4j.properties文件,右击【resources】,选择【New】,单击【Resource Bundle】
(2).在弹出的对话框中输入:log4j,按【OK】按钮,成功创建。(我这里已经创建好了,你们自己按照步骤创建即可)
1.右击【net.army.mr】,选择【New】,单击【Java Class】
@Override
public void map(LongWritable key, Text value, Context context) {
String line = value.toString();
String[] nums = line.split(" ");
for (String num : nums) {
try {
if (!num.isEmpty()) {
int numValue = Integer.parseInt(num.trim());
repToRecordMap.put(numValue, " ");
if (repToRecordMap.size() > 5) {
repToRecordMap.remove(repToRecordMap.firstKey());
}
}
} catch (NumberFormatException e) {
// 可以记录错误信息或者忽略这个值
System.err.println("无法解析的数字: " + num);
}
}
}
@Override
编写MapReduce程序运行主类TopNDriver,主要用于设置MapReduce工作任务的相关参数,对HDFS上/topn/input目录下的源文件求前N数据,并将结果输入到HDFS的/topn/output目录下。
1.右击【net.army.mr】,选择【New】,单击【Java Class】
2编写代码:
1.右击【net.army.mr】,选择【New】,单击【Java Class】
查看结果文件,输入命令:cat part-r-00000
注意修改这两个地方的代码
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。