MapReduce(一)基础简介和Wordcount实例

MapReduce是一种离线批式计算框架,与Spark streaming、flink等流式计算框架不同,其输入数据是固定不可变的,延时较高,适合处理大批量实时分析的场景。
MapReduce源于:2004年12月Google发表的论文,其特点:
1)易于编程;
2)良好的扩展性;
3)高容错性;
4)适合PB级以上海量数据离线处理

应用场景:
流量统计/单词统计/最流行的K个搜索词/复杂算法实现

MR编程模型:
MapReduce(一)基础简介和Wordcount实例_第1张图片
MR执行过程
1)数据会被切割成数据分片;-Split
2)数据片段以key和value的形式被读进来,默认是以行下标作为key,以行的内容作为value。-InputFormat
3)数据会传入Map中进行处理,处理逻辑由用户自定义,在处理完后以key和value形式输出;-Mapper
4)输出的数据经过shuffle,shuffle主要进行数据的排序、分组和合并等操作,shuffle处理的数据不会对原数据进行改变。默认以ASCII码排序-Shuffle
5)数据随后传给Reduce进行处理,处理完后生成k3和v3-Reducer
6)Reduce处理完后的数据会被写到hdfs的某个目录中。-Output

注意:Map-Reduce的思想就是“分而治之”。
Mapper负责“分”,即把“复杂的任务”分解为若干简单的任务执行。
Map处理数据在内存中(buffer in memory),内存放不下时,spill到disk上。

实例:WordCount
首先在pom文件中引入需要添加的依赖pom.xml:

<properties>
        <project.build.directory>.</project.build.directory>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>${
     java.version}</maven.compiler.source>
        <maven.compiler.target>${
     java.version}</maven.compiler.target>
        <maven.version>3.5.0</maven.version>
        <hadoop.version>2.6.5</hadoop.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>${
     hadoop.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>${
     hadoop.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>${
     hadoop.version}</version>
        </dependency>
    </dependencies>

(一)Mapper端代码:

package cn.sendto.wordcount;

/**
 * @Author: lf
 * @Date: 2020-07-16 18:51
 * @Version 1.0
 */
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;


//
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable>{
     
    private final static IntWritable intValue = new IntWritable(1);
    private Text keyword = new Text();
    @Override
    protected void map(LongWritable key, Text value, Context context)
            throws IOException, InterruptedException{
     
        // 空格分词
        String[] str = value.toString().split(" ");
        for (String item: str) {
     
            if(item.isEmpty()) {
     
                continue;
            }
            keyword.set(item);
            context.write(keyword, intValue);
        }

    }
}

继承Reducer类,传入Mapper的输入k,v和输出k,v类型:
输入k:LongWritable=>行offset;输入v:Text=>行内容
输出:k=>Text;输出v:IntWritable=>行号
Writable=>序列化的
重新实现map方法:主要的业务逻辑
(二)Reducer

package cn.sendto.wordcount;

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

/**
 * @Author: lf
 * @Date: 2020-07-17 9:43
 * @Version 1.0
 */
public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
     
    private IntWritable wordNum = new IntWritable();
    @Override
    protected void reduce(Text key, Iterable<IntWritable> value, Context context)
    throws IOException, InterruptedException{
     
        int sum = 0;
        for(IntWritable i: value) {
     
            sum += i.get();
        }
        wordNum.set(sum);
        context.write(key, wordNum);

    }
}

继承Reduce类:Reducer
//Mapper的输出时reduce的输入
reduce方法Text, Iteratable, Context
求和运算,结束后通过context.write()写入

(三)主入口

package cn.sendto.wordcount;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.io.Text;
import java.io.IOException;

/**
 * @Author: lf
 * @Date: 2020-07-17 10:22
 * @Version 1.0
 */
public class MRRunJob {
     
    public static void main(String[] args) {
     
        Configuration conf = new Configuration();

        // NameNode ip
        conf.set("fs.defaultFS", "hdfs://10.45.154.209:8020");
//        conf.set("mapreduce.framework.name","local");
        Job job = null;
        try {
     
            job = Job.getInstance(conf, "mywc");

        } catch (IOException e1) {
     
            e1.printStackTrace();
        }
        job.setJarByClass(MRRunJob.class);
        // Mapper类名
        job.setMapperClass(WordCountMapper.class);
        // Reducer类名
        job.setReducerClass(WordCountReducer.class);
        // Map输出key类型、value类型
        job.setOutputKeyClass(Text.class);

        job.setOutputValueClass(IntWritable.class);

        try {
     
            // 读取文件的位置
            FileInputFormat.setInputPaths(job, new Path("/user/LF/data/input/"));
            FileOutputFormat.setOutputPath(job, new Path("/user/LF/data/output/"));
            //提交job给hadoop集群,等待作业完成后main方法才会结束
            boolean f = job.waitForCompletion(true);
        } catch (Exception e) {
     
            e.printStackTrace();
        }


    }
}

主要是设置hdfs地址、创建job实例、设置map、reduce的相关类,以及Map的输出k,V类型。注意输出目录的地址不能存在,否则无法执行。

上面所有准备好后,还需要对hadoop内部的NativeIO文件进行修改,否则会报:Exception in thread “main” java.lang.UnsatisfiedLinkError:org.apache.hadoop.io.native.NativeID$Windows.access

1)首先打开文件NativeIO
方法:按两次shift,搜索NativeIO文件,选中红色框区域内容,点击进去,复制其文件内容
MapReduce(一)基础简介和Wordcount实例_第2张图片
2)创建org.apache.hadoop.io.nativeio包,创建NativeIO类,用复制内容替换NativeIO中内容
MapReduce(一)基础简介和Wordcount实例_第3张图片
3)在NativeIO类中找到access0返回值所在的方法,将返回参数改成return true。如下图所示。
MapReduce(一)基础简介和Wordcount实例_第4张图片
这样即可本地运行。

集群运行方式:
maven打包后,放到需要指定的服务器上,输入命令:

hadoop jar word_count-1.0-SNAPSHOT.jar cn.sendto.wordcount.MRRunJob

格式:hadoop jar xx.jar 主类名

你可能感兴趣的:(大数据计算-MapReduce,大数据分析,mapreduce,大数据,wordcount,离线计算,mr入门)