实验目的
- 通过实验掌握基本的MapReduce编程方法。
- 掌握用MapReduce解决一些常见的数据处理问题,包括数据去重、数据排序和数据挖掘等。
- 通过操作MapReduce的实验,模仿实验内容,深入理解MapReduce的过程,熟悉MapReduce程序的编程方式。
实验平台
- 操作系统:Ubuntu-16.04
- Hadoop版本:2.6.0
- JDK版本:1.8
- IDE:Eclipse
实验内容和要求
一,编程实现文件合并和去重操作:
-
对于两个输入文件,即文件A和文件B,请编写MapReduce程序,对两个文件进行合并,并剔除其中重复的内容,得到一个新的输出文件C。下面是输入文件和输出文件的一个样例供参考。
- 输入文件f1.txt的样例如下:
20150101 x
20150102 y
20150103 x
20150104 y
20150105 z
20150106 x
- 输入文件f2.txt的样例如下:
20150101 y
20150102 y
20150103 x
20150104 z
20150105 y
- 根据输入文件f1和f2合并得到的输出文件的样例如下:
20150101 x
20150101 y
20150102 y
20150103 x
20150104 y
20150104 z
20150105 y
20150105 z
20150106 x
实验过程:
-
创建文件f1.txt和f2.txt
-
在HDFS建立input文件夹(执行这步之前要开启hadoop相关进程)
-
上传样例到HDFS中的input文件夹
- 接着打开eclipse
Eclipse的使用-
点开项目,找到 src 文件夹,右键选择 New -> Class
-
输入 Package 和 Name,然后Finish
-
写好Java代码(给的代码里要修改HDFS和本地路径),右键选择 Run As -> Run on Hadoop,结果在HDFS系统中查看
-
实验代码:
package cn.edu.zucc.mapreduce;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
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 Merge {
public static class Map extends Mapper
模仿上题完成以下内容:对于两个输入文件,即文件A和文件B,请编写MapReduce程序,对两个文件进行统计单词数量,得到一个新的输出文件C。下面是输入文件和输出文件的一个样例供参考。
- 输入文件a.txt的样例如下:
hello world
wordcount java
android hbase
hive pig
- 输入文件b.txt的样例如下:
hello hadoop
spring mybatis
hive hbase
pig android
- 输出文件的结果为:
android 2
hadoop 1
hbase 2
hello 2
hive 2
java 1
mybatis 1
pig 2
spring 1
wordcount 1
world 1
实验代码:
package cn.edu.zucc.mapreduce;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
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 WordCount {
public static class Map extends Mapper
二,编写程序实现对输入文件的排序:
-
现在有多个输入文件,每个文件中的每行内容均为一个整数。要求读取所有文件中的整数,进行升序排序后,输出到一个新的文件中,输出的数据格式为每行两个整数,第一个数字为第二个整数的排序位次,第二个整数为原待排列的整数。下面是输入文件和输出文件的一个样例供参考。
- 输入文件file1.txt的样例如下:
33
37
12
40
- 输入文件file2.txt的样例如下:
4
16
39
5
- 输入文件file3.txt的样例如下:
1
45
25
- 根据输入文件file1.txt、file2.txt和file3.txt得到的输出文件如下:
1 1
2 4
3 5
4 12
5 16
6 25
7 33
8 37
9 39
10 40
11 45
实验过程:
-
创建文件file1.txt、file2.txt和file3.txt
-
在HDFS建立input2文件夹
-
上传样例到HDFS中的input2文件夹
- 到eclipse上执行代码
实验代码:
package cn.edu.zucc.mapreduce;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
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 ContentSort {
public static class Map extends Mapper
模仿上题完成以下内容:对于三个输入文件,即文件math、文件china和文件english,请编写MapReduce程序,对三个文件进行统计平均分,得到一个新的输出文件。下面是输入文件和输出文件的一个样例供参考。
- 输入文件math.txt的样例如下:
张三 88
李四 99
王五 66
赵六 77
- 输入文件algs.txt的样例如下:
张三 78
李四 89
王五 96
赵六 67
- 输入文件english.txt的样例如下:
张三 80
李四 82
王五 84
赵六 86
- 输出文件结果为:
张三 82
李四 90
王五 82
赵六 76
实验代码:
package cn.edu.zucc.mapreduce;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
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.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
public class AvgScore {
public static class Map extends Mapper {
@Override
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
String line = value.toString();
String[] nameAndScore = line.split(" ");
List list = new ArrayList<>(2);
for (String nameOrScore : nameAndScore) {
if (!"".equals(nameOrScore)) {
list.add(nameOrScore);
}
}
context.write(new Text(list.get(0)), new IntWritable(Integer.parseInt(list.get(1))));
}
}
public static class Reduce extends Reducer {
@Override
public void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException {
int sum = 0;
int count = 0;
for (IntWritable value : values) {
sum += Integer.parseInt(value.toString());
count++;
}
int average = sum / count;
context.write(key, new IntWritable(average));
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://localhost:9000");
String[] otherArgs = new String[]{"input_2", "output_2"};
if (otherArgs.length != 2) {
System.err.println("Usage: AvgScore ");
System.exit(2);
}
Job job = Job.getInstance(conf, "AvgScore");
job.setJarByClass(AvgScore.class);
job.setMapperClass(Map.class);
job.setReducerClass(Reduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
三,对给定的表格进行信息挖掘:
-
下面给出一个child-parent的表格,要求挖掘其中的父子辈关系,给出祖孙辈关系的表格。
- 输入文件table.txt内容如下:
child parent
Steven Lucy
Steven Jack
Jone Lucy
Jone Jack
Lucy Mary
Lucy Frank
Jack Alice
Jack Jesse
David Alice
David Jesse
Philip David
Philip Alma
Mark David
Mark Alma
- 输出文件内容如下:
grandchild grandparent
Mark Jesse
Mark Alice
Philip Jesse
Philip Alice
Jone Jesse
Jone Alice
Steven Jesse
Steven Alice
Steven Frank
Steven Mary
Jone Frank
Jone Mary
实验过程:
-
创建文件table
-
在HDFS建立input3文件夹
-
上传样例到HDFS中的input3文件夹
- 到eclipse上执行代码
实验代码:
package cn.edu.zucc.mapreduce;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
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 STJoin {
public static int time = 0;
public static class Map extends Mapper
模仿上题完成以下内容:现有两个输入文件两个文件,一个是工厂名与地址编号的对应关系;另一个是地址编号和地址名的对应关系。要求从输入数据中找出工厂名和地址名的对应关系,输出"工厂名——地址名"表。
- 输入文件factory.txt:
factoryname addressID
Beijing Red Star 1
Shenzhen Thunder 3
Guangzhou Honda 2
Beijing Rising 1
Guangzhou Development Bank 2
Tencent 3
Bank of Beijing 1
- 输入文件address.txt:
addressID addressname
1 Beijing
2 Guangzhou
3 Shenzhen
4 Xian
- 输出文件内容如下:
factoryname addressname
Back of Beijing Beijing
Beijing Rising Beijing
Beijing Red Star Beijing
Guangzhou Development Bank Guangzhou
Guangzhou Honda Guangzhou
Tencent Shenzhen
Shenzhen Thunder Shenzhen
实验代码:
package cn.edu.zucc.mapreduce;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
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;
import org.apache.hadoop.util.GenericOptionsParser;
public class MTJoin {
public static int time = 0;
public static class Map extends Mapper