分布式计算框架MapReduce入门

分布式计算框架MapReduce入门

mapreduce的核心思想是:分而治之

map:把复杂的任务分解成若干的简单任务来并行执行,前提是这些小任务可以并行计算,彼此之间没有依赖

reduce:对map阶段的结果进行汇总

MapReduce编程规范和示例编写

mapreduce的编程模型

mapreduce的开发一共有八个步骤:其中map阶段分为2个步骤,shuffle阶段四个步骤,reduce阶段分为2个步骤

Map阶段的两个步骤:

第一步:设置inputFormat类,将我们的数据切分成K1、V1对,输入到第二步

第二步:自定义map逻辑,处理传入的数据,然后转换成K2、V2对输出

shuffle阶段4个步骤(之后会详细讲解)

第三步:分区,将相同的K2的数据发送到同一个reduce去,形成集合

第四步:排序,对数据进行字典顺序的排列

第五步:规约,在map端进行一次数据的聚合,减少K2的数据量

第六步:分组,将相同的数据发送到同一组去调用reduce逻辑

Reduce阶段两个步骤

第七步:自定义reduce逻辑,接收K2、V2转换成K3、V3进行输出

第八步:输出 将reduce处理完成的数据进行输出

wordCount示例

需求:在给定的文本文件中统计每个单词的出现的次数

在hdfs上一个文件wordcount.txt

hello,world,hadoop
hive,sqoop,flume,hello
kitty,tom,jerry,world
hadoop

Mapper类

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

public class wordCountMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
    /**
     * 自定义map逻辑
     * @param key K1
     * @param value V1
     * @param context 上下文
     * @throws IOException
     * @throws InterruptedException
     */
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String[] split = value.toString().split(",");
        for (String s : split) {
            context.write(new Text(s),new IntWritable(1));
        }
    }
}

Reducer类

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;

public class wordCountReducer extends Reducer<Text, IntWritable,Text,IntWritable> {
    /**
     * 自定义reduce逻辑
     * @param key K2
     * @param values V2
     * @param context 上下文
     * @throws IOException
     * @throws InterruptedException
     */
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        int count = 0;
        for (IntWritable value : values) {
            count += value.get();
        }
        context.write(key,new IntWritable(count));
    }
}

JobMain类

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
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.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class JobMain extends Configured implements Tool {
    @Override
    public int run(String[] args) throws Exception {
        Job job = Job.getInstance(super.getConf(), JobMain.class.getSimpleName());
        //打包到集群上面运行时候,必须要添加以下配置,指定程序的main函数
        job.setJarByClass(JobMain.class);
        //第一步:读取输入文件解析成key,value对
        job.setInputFormatClass(TextInputFormat.class);
        TextInputFormat.addInputPath(job,new Path("hdfs://node01:8020/wordCount"));

        //第二步:设置我们的mapper类
        job.setMapperClass(wordCountMapper.class);
        //设置我们map阶段完成之后的输出类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);
        //第三步,第四步,第五步,第六步,省略
        //第七步:设置我们的reduce类
        job.setReducerClass(wordCountReducer.class);
        //设置我们reduce阶段完成之后的输出类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        //第八步:设置输出类以及输出路径
        job.setOutputFormatClass(TextOutputFormat.class);
        TextOutputFormat.setOutputPath(job,new Path("hdfs://node01:8020/wordcount_out"));
        boolean b = job.waitForCompletion(true);
        return b?0:1;
    }

    /**
     * 程序main函数的入口类
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        Configuration configuration = new Configuration();
        Tool tool  =  new JobMain();
        int run = ToolRunner.run(configuration, tool, args);
        System.exit(run);
    }
}

两种集群运行方式:

jar包运行:把项目打成jar包,上传到hdfs系统上,再使用命令运行

本地运行:修改文件的读取和结果写入地址,再添加本地运行配置

configuration.set("mapreduce.framework.name","local");
        configuration.set("yarn.resourcemanager.hostname","local");
TextInputFormat.addInputPath(job,new Path("file:///D:\\wordcount\\input"));
TextOutputFormat.setOutputPath(job,new Path("file:///D:\\wordcount\\output"));


本地运行时可能会出现如下错误:org.apache.hadoop.io…windows.creata…

出现这种错误,可能是jar包不兼容的问题,将导入的CHD版本的改成Hadoop版本的原生jar包再执行,程序完美运行

猜你喜欢

转载自blog.csdn.net/lsy107816/article/details/84964693