Mapreducer程序写了好几个了,但是之前一直都没有仔细的测试过本地运行和集群上运行的区别,今天写了一个Mapreduce程序,在此记录下来。
本地运行注意事项有以下几点:
1、本地必须配置好Hadoop的开发环境
2、在src里不加入配置文件运行,或者如果本地的src里有mapred-site.xml和yarn-site.xml配置文件,那么mapreduce.framework.name=local以及yarn.resourcemanager.hostname=local
测试说明:src里的配置文件修改为本地后打出jar包到集群运行,测试发现读取的是集群的配置文件,而不是本地src里面的配置文件,src配置主要是在本地运行时读取,没有 配置那么读取的是default.xml配置文件
以下是Mapreduce的代码:
package cn.zxl.mrlocalrun;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
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.output.FileOutputFormat;
public class MapreduceLocalRunTest {
static class MapreduceLocalRunTestMapper extends Mapper<LongWritable, Text, Text, Text>{
@Override
protected void map(LongWritable key, Text value,Context context)
throws IOException, InterruptedException {
String line=value.toString();
String[] fields=line.split("@");
String name=fields[0];
String idserial=fields[1];
String sex=fields[2];
context.write(new Text(name), new Text(idserial+"\t"+sex));
}
}
//reducer代码块虽然没有写排序,但是默认会根据key进行排序
static class MapreduceLocalRunTestReducer extends Reducer<Text, Text, Text, Text>{
@Override
protected void reduce(Text key, Iterable<Text> values,Context context)
throws IOException, InterruptedException {
for(Text value:values){
context.write(key, value);
}
}
}
//本地运行程序测试,不在Hadoop集群测试程序
//特别说明:本地必须配置好Hadoop的开发环境,在src里不加入配置文件运行,
//如果本地的src里有mapred-site.xml和yarn-site.xml配置文件,那么mapreduce.framework.name=local以及yarn.resourcemanager.hostname=local
//src里的配置文件修改为本地后打出jar包到集群运行,测试发现读取的是集群的配置文件,而不是本地src里面的配置文件,src配置主要是在本地运行时读取,没有配置那么读取的是default.xml配置文件
/**
* 说明:main右键--->选择Run As--->Run Configuration--->Name:指定运行的类名;
* Main里:Protect指定工程名; Main class指定主函数的包名+类名--->Arguments里的Program arguments:
* 指定要输入的参数,本类指定输入数据源和输出数据源的路径E:\localrun\data\Users.txt E:\localrun\data\out
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Configuration conf=new Configuration();
Job job=Job.getInstance(conf);
//指定jar类
job.setJarByClass(MapreduceLocalRunTest.class);
//指定mapper和reducer类
job.setMapperClass(MapreduceLocalRunTestMapper.class);
job.setReducerClass(MapreduceLocalRunTestReducer.class);
//job.setNumReduceTasks(0);//不运行reducer,程序也不会进行排序
//指定map输出key和value的类型,如果和reducer类型一致,mapper的输出可以省略不写,默认和reducer一致
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
//指定reducer的key和value输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
//分别指定数据源的输入和数据的输出路径,在集群上输入的是hdfs里的路径,而不是本地路径
FileInputFormat.setInputPaths(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.waitForCompletion(true);
}
}
src下的mapred-site配置文件:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!-- Put site-specific property overrides in this file. -->
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>local</value>
</property>
</configuration>
yarn-site.xml:
<?xml version="1.0"?>
<configuration>
<!-- Site specific YARN configuration properties -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>local</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
测试数据:
Jenny@123456@girl
Jack@456789@boy
Tom@012345@boy
Luccy@987654@girl