Hadoop集群搭建前安装准备参考:
一、Hadoop系统应用之安装准备(一)(超详细步骤指导操作,WIN10,VMware Workstation 15.5 PRO,CentOS-6.7)
一、Hadoop系统应用之安装准备(二)(超详细步骤指导操作,WIN10,VMware Workstation 15.5 PRO,CentOS-6.7)
Hadoop集群搭建过程参考:
二、Hadoop系统应用之Hadoop集群搭建(超详细步骤指导操作,WIN10,VMware Workstation 15.5 PRO,CentOS-6.7)
MapReduce简介及操作实例之词频统计参考:
五、Hadoop系统应用之MapReduce分布式计算框架(一)(超详细步骤指导操作,WIN10,VMware Workstation 15.5 PRO,CentOS-6.7)
文章目录
操作实例之倒排索引(本地运行模式)
在本地运行模式使用MapReduce程序实现倒排索引功能。
1、MapReduce操作原理
- 首先,使用默认的TextInputFormat类对每个输入文件进行处理,得到文本中每行的偏移量及其内容。例如输入文本text1.txt内容为MapReduce is simple,输入文本text2.txt内容为MapReduce is easy,分别转换为<0,MapReduce is simple>,<0,MapReduce is easy is powerful>。
- Map过程首先分析输入的<key,value>键值对,经过处理可以得到倒排索引中需要的三个信息:单词、文档名称和词频。如<MapReduce:text1.txt list(1)>,<is:text1.txt list(1)>,<simple:text1.txt list(1)>,<MapReduce:text2.txt list(1)>,<is:text2.txt list(1,1)>,<easy:text2.txt list(1)>,<powerful:text2.txt list(1)>。
- 经过Map阶段数据转换后,同一个文档中相同的单词会出现多个的情况,而单纯依靠后续Reduce阶段无法同时完成词频统计和生成文档列表,所以必须增加一个Combine阶段,先完成每一个文档的词频统计。如<MapReduce text1.txt:1>,<is text1.txt:1>,<simple text1.txt:1>,<MapReduce text2.txt:1>,<is text2.txt:2>,<easy text2.txt:1>,<powerful text2.txt:1>。
- 经过上述两个阶段的处理后,Reduce阶段只需将所有文件中相同key值的value值进行统计,并组合成倒排索引文件所需的格式即可。如<MapReduce text1.txt:1;text2.txt:1>,<is text1.txt:1;text2.txt:2>,<simple text1.txt:1>,,<easy text2.txt:1>,<powerful text2.txt:1>。
2、操作过程
(需启动集群的HDFS和YARN服务)
2.1 包的创建
在src/main/java下新建Package,名为cn.itcast.mr.invertedIndex。之后分别在该包下创建四个类文件:InvertedIndexMapper.java、InvertedIndexCombiner.java、InvertedIndexReduce.java、InvertedIndexDriver.java。
2.2 Mapper类文件的创建
在InvertedIndexMapper.java文件下新增如下内容,实现MapReduce的Map阶段:
public class InvertedIndexMapper extends Mapper<LongWritable, Text, Text, Text> {
private static Text keyInfo = new Text();// 存储单词和 URL 组合
private static final Text valueInfo = new Text("1");// 存储词频,初始化固定为1
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//拆分行文本数据,得到单词个数
String line = value.toString();
String[] fields = StringUtils.split(line, " ");// 得到字段数组fields
//获取行文本数据所在的文件名
FileSplit fileSplit = (FileSplit) context.getInputSplit();// 得到这行数据所在的文件切片
String fileName = fileSplit.getPath().getName();// 根据文件切片得到文件名
//将K2、V2写入上下文中
for (String field : fields) {
// key值由单词和URL组成,如“MapReduce:file1”
keyInfo.set(field + ":" + fileName);
context.write(keyInfo, valueInfo);
}
}
}
注:上述java文件内容未加入包的导入部分未进行展示,可在抛出异常时进行添加,下同。
2.3 Combiner类文件的创建
在InvertedIndexCombiner.java文件下新增如下内容,自定义实现Combine阶段的类:
public class InvertedIndexCombiner extends Reducer<Text, Text, Text, Text> {
private static Text info = new Text();
// 输入:<MapReduce:file3 {1,1,...}>
// 输出:<MapReduce file3:2>
@Override
protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
//遍历集合,统计每个单词出现的次数
int sum = 0;
for (Text value : values) {
sum += Integer.parseInt(value.toString());//Integer.parseInt把字符串1变成整型1
}
//获取文件名
int splitIndex = key.toString().indexOf(":");//返回冒号第一次出现的索引
// 重新设置 value值由 URL和词频组成
info.set(key.toString().substring(splitIndex + 1) + ":" + sum);
// 重新设置 key值为单词
key.set(key.toString().substring(0, splitIndex));//从0位开始截到冒号前一个单词为止
//将Key和Value写入上下文中
context.write(key, info);
}
}
2.4 Reducer类文件的创建
在InvertedIndexReduce.java文件下新增如下内容,实现MapReduce的Reduce阶段:
public class InvertedIndexReducer extends Reducer<Text, Text, Text, Text> {
private static Text result = new Text();
// 输入:<MapReduce file3:2>
// 输出:<MapReduce file1:1;file2:1;file3:2;>
@Override
protected void reduce(Text key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
// 遍历集合,拼接集合内容,生成文档列表
String fileList = new String();
for (Text value : values) {
fileList += value.toString() + ";";
}
result.set(fileList);
//将K3、V3写入上下文
context.write(key, result);
}
}
2.5 驱动类文件的创建
在InvertedIndexDriver.java文件下新增如下内容,进行程序的提交:
public class InvertedIndexDriver {
public static void main(String[] args) throws IOException,
ClassNotFoundException, InterruptedException {
//获取Job任务对象
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
//设置Job任务对象
job.setJarByClass(InvertedIndexDriver.class);
job.setMapperClass(InvertedIndexMapper.class);
job.setCombinerClass(InvertedIndexCombiner.class);
job.setReducerClass(InvertedIndexReducer.class);
//设置输出K3、V3类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
//设置源文件的输入路径
FileInputFormat.setInputPaths(job, new Path("D:\\hadoop-1\\InvertedIndex\\input"));
//指定处理完成之后的结果所保存的位置
FileOutputFormat.setOutputPath(job, new Path("D:\\hadoop-1\\InvertedIndex\\output"));
//启动 Job任务
boolean res = job.waitForCompletion(true);//执行成功返回true
System.exit(res ? 0 : 1);
}
}
2.6 操作内容
在WordCountDriver.java中待处理数据所在的路径下新建相关的文件夹,并新建待处理的txt文本信息,路径与内容如下:
2.7 运行结果
在WordCountDriver.java文件下右键点击运行,以Java应用的形式进行运行,获得结果。
结果将保存在WordCountDriver.java中写好的保存路径下。
参考文献:黑马程序员.Hadoop大数据技术原理与应用[M].北京:清华大学出版社,2019.
后续学习链接:
六、Hadoop系统应用之Zookeeper分布式协调服务(一)(超详细步骤指导操作,WIN10,VMware Workstation 15.5 PRO,CentOS-6.7)