Hadoop之mapreduce 实例一
hadoop之mapreduce 实例一
统计hello文件中 字符的个数.
-------------------
hello you
hello me
-------------------
MapReducer的执行过程
1.map处理阶段
1.1读取HDFS的输入文件中的内容,把每一行解析成一个<k1,v1>对。
k1表示每一行的起始位置(单位byte),v1表示每一行的文本内容。每个键值对调用一次map函数。
问:一共可以解析成多少个<k1,v1>?
答:2个,分别是<0, hello you>,<10, hello me>,一共2次map函数
1.2覆盖map函数,实现自己的业务逻辑。对输入的<k1,v1>做处理,转化为新的<k2,v2>输出。
void map(k1,v1, context){
String[] splited = v1.split('\t');
for(String word : splited){
context.write(<k2,v2>);
}
}
分别是<hello,1><you,1><hello,1><me,1>
1.3对map输出的<k2,v2>做分区。默认有1个分区。
1.4每个分区中的<k2,v2>按照k2进行排序、分组。分组指的是把相同k的v放到一个集合中。相同key的value放到一个集合中。
排序后<hello,1><hello,1><me,1><you,1>
分组后<hello,{1,1}><me,{1}><you,{1}>
1.5归约
2.reduce处理阶段
2.1对多个map的输出,按照不同的分区,通过网络copy到不同的reduce节点。
2.2对多个map的输出,进行合并、排序。覆盖reduce函数,实现自己的业务逻辑,对输入的<k2,v2s>进行处理,转化为新的<k3,v3>输出。
void reduce(k2,v2s, context){
long sum=0L;
for(long times : v2s){
sum += times;
}
context.write(k2,sum);
}
2.3把<k3,v3>写入到hdfs中
源码如下:
/** * 假设有个目录结构 * /dir1 * /dir1/hello.txt * /dir1/dir11/hello.bat * * 问:统计/dir1下面所有的文件中的单词技术 * */ public class WortCountTest {
// 驱动代码 public static void main(String[] args) throws Exception{ Configuration conf = new Configuration(); String jobName = WortCountTest.class.getSimpleName(); Job job = Job.getInstance(conf, jobName); //要把代码打包运行, 调用如下行 job.setJarByClass(WortCountTest.class); //指定输入路径 FileInputFormat.setInputPaths(job, new Path("hdfs://zzy:9000/hello")); //指定解析<k1,v1>的类 //job.setInputFormatClass(TextInputFormat.class); //指定自定义的mapper类 job.setMapperClass(MyMapper.class); //指定输出的<k2,v2>类型 //当<k3,v3>的类型与<k2,v2>类型一致时,<k2,v2>类型可以不指定 //job.setMapOutputKeyClass(Text.class); //job.setMapOutputValueClass(LongWritable.class); //指定自定义reducer类 job.setReducerClass(MyReducer.class); //指定输出的<k3,v3>类型 job.setOutputKeyClass(Text.class); job.setOutputValueClass(LongWritable.class); //指定输出<k3,v3>的类 //job.setOutputFormatClass(TextOutputFormat.class); //指定输出的路径 FileOutputFormat.setOutputPath(job, new Path("hdfs://zzy:9000/out1")); job.waitForCompletion(true); } private static class MyMapper extends Mapper<LongWritable, Text, Text, LongWritable>{ Text k2 = new Text(); LongWritable v2 = new LongWritable(); @Override protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, LongWritable>.Context context) throws IOException, InterruptedException { String line = value.toString(); String[] splited = line.split("\t"); //word表示每一行中的每个单词 for (String word : splited) { k2.set(word); v2.set(1L); context.write(k2, v2); } } } private static class MyReducer extends Reducer<Text, LongWritable, Text, LongWritable>{ LongWritable v3 = new LongWritable(); @Override protected void reduce(Text k2, Iterable<LongWritable> v2s, Reducer<Text, LongWritable, Text, LongWritable>.Context context) throws IOException, InterruptedException { long sum = 0L; for (LongWritable v2 : v2s) { sum += v2.get(); } v3.set(sum); context.write(k2, v3); } } }