MapReduce分布式编程

    xiaoxiao2025-07-29  18

    MapReduce分布式编程

     

    实验目的及要求

    本次上机实验所涉及并要求掌握的知识点

    实验环境

    Eclipse、Hadoop

    实验步骤

    MapReduce编程入门实例之WordCount:分别在Eclipse和Hadoop集群上运行  首先看一下我的项目结构和WordCount程序: 其中word.txt将作为我们测试的输入文件,内容如下:   hello hadoop  hello wordcount    程序代码: package com.hadoop.WordCount;  import java.io.IOException;  import java.util.StringTokenizer;  import org.apache.hadoop.conf.Configuration;  import org.apache.hadoop.fs.FileSystem;  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.input.TextInputFormat;  import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;  @SuppressWarnings("unused")  public class WordCount {  public static class TokenizerMapper extends  Mapper<Object, Text, Text, IntWritable>  // 为什么这里k1要用Object、Text、IntWritable等,而不是java的string啊、int啊类型,当然,你可以用其他的,这样用的好处是,因为它里面实现了序列化和反序列化。  // 可以让在节点间传输和通信效率更高。这就为什么hadoop本身的机制类型的诞生。  //这个Mapper类是一个泛型类型,它有四个形参类型,分别指定map函数的输入键、输入值、输出键、输出值的类型。hadoop没有直接使用Java内嵌的类型,而是自己开发了一套可以优化网络序列化传输的基本类型。  //这些类型都在org.apache.hadoop.io包中。  //比如这个例子中的Object类型,适用于字段需要使用多种类型的时候,Text类型相当于Java中的String类型,IntWritable类型相当于Java中的Integer类型 {  //定义两个变量或者说是定义两个对象,叫法都可以  private final static IntWritable one = new IntWritable(1);//这个1表示每个单词出现一次,map的输出value就是1.  //因为,v1是单词出现次数,直接对one赋值为1  private Text word = new Text(); public void map(Object key, Text value, Context context)  //context它是mapper的一个内部类,简单的说顶级接口是为了在map或是reduce任务中跟踪task的状态,很自然的MapContext就是记录了map执行的上下文,在mapper类中,这个context可以存储一些job conf的信息,比如job运行时参数等,  //我们可以在map函数中处理这个信息,这也是Hadoop中参数传递中一个很经典的例子,同时context作为了map和reduce执行中各个函数的一个桥梁,这个设计和Java web中的session对象、application对象很相似 //简单的说context对象保存了作业运行的上下文信息,比如:作业配置信息、InputSplit信息、任务ID等  //我们这里最直观的就是主要用到context的write方法。  //说白了,context起到的是连接map和reduce的桥梁。起到上下文的作用!  throws IOException, InterruptedException {  //The tokenizer uses the default delimiter set, which is " \t\n\r": the space character, the tab character, the newline character, the carriage-return character  StringTokenizer itr = new StringTokenizer(value.toString());//将Text类型的value转化成字符串类型   //使用StringTokenizer类将字符串“hello,java,delphi,asp,PHP”分解为单个单词  // 程序的运行结果为: // hello // java  // delphi  // asp  // php   while (itr.hasMoreTokens()) {  // 实际上就是java.util.StringTokenizer.hasMoreTokens()  // hasMoreTokens() 方法是用来测试是否有此标记生成器的字符串可用更多的标记。  word.set(itr.nextToken());  context.write(word, one);  }  }  }  public static class IntSumReducer extends  Reducer<Text, IntWritable, Text, IntWritable> {  private IntWritable result = new IntWritable();  public void reduce(Text key, Iterable<IntWritable> values,  Context context) throws IOException, InterruptedException { 62 //我们这里最直观的就是主要用到context的write方法。  //说白了,context起到的是连接map和reduce的桥梁。起到上下文的作用!   int sum = 0;  for (IntWritable val : values) {//叫做增强的for循环,也叫for星型循环  sum += val.get();  }  result.set(sum);  context.write(key, result); } }  public static void main(String[] args) throws Exception {  Configuration conf = new Configuration();//程序里,只需写这么一句话,就会加载到hadoop的配置文件了 //Configuration类代表作业的配置,该类会加载mapred-site.xml、hdfs-sit

     

     

     

     

    最新回复(0)