在hadooop环境hdfs和yarn都可以正常运行之后,既可以实现一个简单的mapreduce实例程序。
本人使用单机伪分布式部署,启动之后有5个进程,并且50070和8088端口都有web程序在运行。
1.实现Mapper类
/**
* Key in 框架读到的一行数据的起始偏移量
* value in 读到的一行数据的内容
* key out 业务逻辑输出的数据key类型
* value out 业务逻辑数据的数据value类型
* <p>
* <p>
* 由于java序列化方式冗余数据较多,故hadoop实现了一个序列化机制,所以处理数据和返回数据时需要使用Hadoop实现的数据包装类
* Long --- LongWritable
* String -- Text
* Integer -- IntWritable
* Null -- NullWritable
*/
public class DemoMapper extends Mapper<LongWritable, Text, Text, LongWritable> {
/**
* @param key key in
* @param value value in
* @param context Hadoop上下文,提供数据输出等功能
* @throws IOException e
* @throws InterruptedException e
*/
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//转换为Java原生类型
String line = value.toString();
//分割一行数据
String[] words = line.split(" ");
for (String str : words) {
context.write(new Text(str), new LongWritable(1));
}
}
}
2.实现Reducer类
/**
* key in map阶段输出的Key的类型
* value in map阶段输出的value类型
* key out reduce结果数据key类型
* value out reduce结果输出value类型
*/
public class DemoReducer extends Reducer<Text, LongWritable, Text, LongWritable> {
/**
* 一组相同key的数据调用一次reduce方法
*
* @param key map阶段产生的key
* @param values map阶段产生的value迭代器
* @param context hadoop上下文
* @throws IOException e
* @throws InterruptedException e
*/
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
//遍历所有Value
long count = 0;
for (LongWritable value : values) {
//转换为Java原生类型
long currentCount = value.get();
//累加
count += currentCount;
}
//输出结果,不需要操作HDFS,系统会将结果自动输出到HDFS
context.write(key, new LongWritable(count));
}
}
3.发布作业到Yarn上运行
//配置Yarn的位置
Configuration conf = new Configuration();
conf.set("yarn.resourcemanager.hostname", "192.168.1.11");
//获取作业提交器
Job job = Job.getInstance(conf);
//设置作业Jar包位置,jar位置由类加载器寻找
job.setJarByClass(Main.class);//or job.setJar("jar位置")
//设置启动ReduceTask的数量
job.setNumReduceTasks(1);
//设置Mapper和Reducer的实现类(业务实现类)
job.setMapperClass(DemoMapper.class);
job.setReducerClass(DemoReducer.class);
//设置map阶段和reduce阶段输出的数据类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
//设置待处理文件位置
FileInputFormat.setInputPaths(job, new Path("/wordcount/input/"));
//设置处理结果文件位置
FileOutputFormat.setOutputPath(job, new Path("/wordcount/output/"));
//提交作业
boolean successed = job.waitForCompletion(true); //or job.submit()
//判断作业是否执行成功
if (successed) {
System.exit(0);
} else {
System.exit(200);
}
}
4.打包成jar文件并拷贝到Linux环境中运行,理论上在windows开发环境中也可以运行,当为了避免windows环境和实际运行环境的冲突,所以还是在linux环境中运行
5.运行程序
hadoop jar mapreduce.jar 主类全名
也可以使用java -jar命令来启动作业,但需要制定类路径等其他参数
6.查看结果
hadoop fs -ls /wordcount/output/
可以看到输出文件下有一个_SUCCESS文件和一个或多个part文件,数量取决于你启动的reduceTask数量,其中part文件就是需要的处理结果,可通过cat 或text命令来查看其中内容
hadoop fs -cat /cordcount/output/part文件名称