用java写的mrWordCount

package com.qf.mr.wordcount.version2;


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.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Partitioner;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.io.IOException;

/**
 *  获取Job对象,初始化job的信息
 */
public class WordCountDriver {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        //获取配置对象
        Configuration conf = new Configuration();
        //获取job对象
        Job job = Job.getInstance(conf, "wordcount");

        //绑定两个阶段的主类
        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReducer.class);

        //设置驱动类型
        job.setJarByClass(WordCountDriver.class);

        //设置K2,V2的类型   注意:当K2与K3不同,就必须设置K2,   当V2与V3不同,就必须设置V2,  如果相同就不需要设置
        //job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        //设置K3,V3的类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(LongWritable.class);

        //使用自定义分区器
        job.setPartitionerClass(WordCountPartitioner.class);


        //设置reduceTask的个数,如果不设置,默认为1个
        job.setNumReduceTasks(5);

         //设置输入输出路径,  注意:我们可以借助main方法的args数组参数,使路径更加灵活
        FileInputFormat.addInputPath(job,new Path("D:\\academia\\The teaching material\\The required data\\data-mr\\wordcount"));
        //先判断输出路径在不在,如果在,就删除。
        Path output = new Path("D:/output");
        FileSystem fileSystem = FileSystem.get(conf);
        if(fileSystem.exists(output)){
            fileSystem.delete(output,true);
        }
        FileOutputFormat.setOutputPath(job,output);

        //提交程序
        System.exit(job.waitForCompletion(true)?0:1);

    }
    public static class WordCountMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
        private Text k2;
        private IntWritable v2;

        /**
         * 执行MapTask任务前会调用一次setup方法
         * @param context
         * @throws IOException
         * @throws InterruptedException
         */
        @Override
        protected void setup(Context context) throws IOException, InterruptedException {
            k2 = new Text();
            v2 = new IntWritable(1);
        }

        /**
         *
         * @param key     是K1   行偏移量
         * @param value   是V1   行记录
         * @param context  上下文,提供了输出方法write, 可以将K2,V2当成键值对输出
         * @throws IOException
         * @throws InterruptedException
         *
         *  注意:每一对K1V1调用一次map函数
         *
         */
        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            //第一步:将value转为java类型的String
            String line = value.toString();
            //第二步:使用空格进行切分,返回数组类型,元素就是单词
            String[] content = line.split(" ");
            //将数组中的元素(单词)封装成K2,   整数1封装成V2 然后使用上下文的write方法写出去即可

            for (String word : content) {
                //将word单词设置到K2身上
                k2.set(word);
                //写出去
                context.write(k2,v2);
            }
        }
    }
    public static class WordCountReducer extends Reducer<Text, IntWritable, Text, LongWritable> {
        private LongWritable v3;

        @Override
        protected void setup(Context context) throws IOException, InterruptedException {
            v3 = new LongWritable();
        }

        /**
         *
         * @param key   是K2  是某一个单词
         * @param values  是v2的集合,也就是有一堆1.
         * @param context
         * @throws IOException
         * @throws InterruptedException
         *
         *   注意: reduce函数的调用的次数与分组的组个数有关系,一组调用一次。默认情况下,一个单词就是一组
         *
         */
        @Override
        protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
            //定义一个变量,用于累加
            long count = 0;
            //只需要将values中的1取出进行累加
            for (IntWritable value : values) {
                //获取基本数类型1
                int temp = value.get();
                count+=1;
            }
            //将累加之和封装成V3,K2作为K3,
            v3.set(count);
            //然后写出去
            context.write(key,v3);
        }


    }
    /**
     * 自定义分区器:
     * 第一步:继承Partitioner
     * 第二步:定义K2V2的泛型
     * 第三步:重写方法
     *
     * 需求: Aa-Nn在0分区,oO-zZ在1分区,其他在2分区
     *
     * 注意:分区号,必须是连续的自然数,从0开头
     */
    public static class WordCountPartitioner extends Partitioner<Text,IntWritable> {

        public int getPartition(Text key, IntWritable value, int numPartitions) {
            String line = key.toString();
            String first = line.substring(0, 1);
            if(first.matches("[A-Na-n]")){
                return 0;
            }else if(first.matches("[O-Zo-z]")){
                return 1;
            }else{
                return 2;
            }
        }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值