Hadoop入门系列2——安装,配置,编程,部署和运行

来源:互联网 发布:数据库业务流程图 编辑:程序博客网 时间:2024/05/21 14:53

Hadoop入门系列1——安装,配置,编程,部署和运行中已经安装并配置了基于伪分布模式的Hadoop平台

之后将介绍Hadoop编程。

package seu.mapreduce.wordcount;

import java.io.IOException;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configured;
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;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

/**
 * 1.新版API中Mapper与Reducer已经不是接口而是抽象类
 * 而且map函数与reduce函数也已经不再实现Mapper和Reducer接口
 * 而是继承Mapper和Reducer抽象类
 *
 * 2.新版API广泛使用context对象,并使用MapContext进行MapReduce间的通信
 * MapContext同时充当OutputCollector和Reporter的角色
 *
 * 3.Job的配置统一由Configuration来完成,而不必额外使用JobConf对守护进程进行配置
 *
 * 4.由Job类来负责Job的控制,而不是JobClient,JobClient在新的API中已经被删除
 * @author wjm
 *
 */
public class WordCount extends Configured implements Tool{
    
    /**
     * Map类是通过继承抽象类Mapper得到的类
     * LongWritable,IntWritable,Text均是Hadoop中实现的用于封装Java数据类型的类
     * 它们能够被串行化从而便于在分布式环境中进行数据交换,可以认为是long,int,String的替代品
     * @author wjm
     *
     */
    public static class Map extends Mapper<LongWritable, Text, Text, IntWritable>{
        private final static IntWritable one = new IntWritable(1);//可以将IntWritable视为int类型
        private Text word = new Text();//将Text视为String类型,其中word代表的是输入的文本
        //自定义的map函数,形式如 void map(K1 key, V1 value, Context context)
        //新版API使用Context对象同时充当原版API中OutputCollector与Reporter的角色,在MapReduce之间进行通信
        //map函数将输入读入后切出其中的单词,并标记它的数目为1,形成<word,1>的形式
        //并通过context进行保存和信息的传递
        public void map(LongWritable key, Text value, Context context )throws IOException, InterruptedException{
            String line = value.toString();//value是Text类型,即String类型。line是由value转换成的字符串
            StringTokenizer tokenizer = new StringTokenizer(line);//按照line的内容进行切分
            while(tokenizer.hasMoreTokens()){
                word.set(tokenizer.nextToken());//word是输入的文本,按照tokenizer进行切分
                context.write(word, one);
            }
        }
    }
    
    /**
     * Reduce类是通过继承抽象类Reducer而形成的类
     * @author wjm
     *
     */
    public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable>{
        /**
         * reduce函数接受context传递的信息(形如<word,1>的键值对),reduce将相同key
         * 也就是word的值(即计数)收集起来,形成<word,list of 1>的形式
         * 之后将这些1值加起来,即为单词的个数
         */
        public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException{
            int sum = 0;
            for(IntWritable val : values){
                sum += val.get();
            }
            context.write(key, new IntWritable(sum));
        }
    }
    
    @Override
    public int run(String[] args) throws Exception {
        /**
         * 原版API使用JobConf类进行map reduce的配置
         * 而新版API的Job的配置完全是由Configuration配置的
         */
        Job job = new Job(getConf());//Job的初始化,Configuration类的getConf()方法对Job进行配置
        job.setJarByClass(WordCount.class);
        job.setJobName("wordcount");//setJobName()命名job,设置一个用户自定义的job名称
        
        job.setOutputKeyClass(Text.class);//为job的输出数据设置Key类
        job.setOutputValueClass(IntWritable.class);//为job的输出设置Value类
        
        //Map和Reduce都是用户自定义的通过继承抽象类而得到的类
        job.setMapperClass(Map.class);//为job设置Mapper类
        job.setReducerClass(Reduce.class);//为job设置Reducer类
        
        //InputFormat描述map-reduce中对job的输入定义
        //OutputFormat描述map-reduce中对job的输出定义
        //TextInputFormat是Hadoop默认的输入法,每个文件都会单独作为map输入
        //TextOutputFormat是Hadoop默认的输出法,将每条记录以一行的形式存入文本文件
        job.setInputFormatClass(TextInputFormat.class);//为map-reduce任务设置InputFormat实现类
        job.setOutputFormatClass(TextOutputFormat.class);//为map-reduce任务设置OutputFormat实现类
        
        //setInputPaths()为map-reduce job设置路径数组作为输入列表
        //setOutputPaths()为map-reduce job设置路径数组作为输出列表
        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        
        boolean success = job.waitForCompletion(true);
        return success ? 0 : 1;
    }

    //main函数
    public static void main(String[] args) throws Exception {
        int ret = ToolRunner.run(new WordCount(), args);
        System.exit(ret);
    }
}


原创粉丝点击