9.hadoop系列之MapReduce实践

1. MapReduce初识

本文开始我们学习hadoop的另一大组成部分:MapReduce

1.1 MapReduce定义

MapReduce是一个分布式运算程序的编程框架。
MapReduce核心功能是将用户编写的业务逻辑代码自带默认组件整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上。

1.2 MapReduce优缺点

优点

  • 易于编程:用户通过实现框架接口,只需关心业务逻辑
  • 良好扩展性:可动态增加服务器,解决计算资源不够问题
  • 高容错性:任何一台机器挂掉,可将任务转移到其他节点
  • 适合海量数据计算(TB/PB): 千台服务器共同计算

缺点

  • 不擅长实时计算
  • 不擅长流式计算
  • 不擅长DAG有向无环图计算

1.3 MapReduce核心编程思想

先了解下大概思想,下一篇文章我们通过wordcount具体案例来深入理解

  1. MapReduce运算程序一般分为两个阶段:Map阶段与Reduce阶段
  2. Map阶段的并发MapTask,完全并行运行,互不相干
  3. Reduce阶段的并发ReduceTask,完全并行运行,互不相干,但是数据依赖于上一阶段所有MapTask并发实例的输出
  4. MapReduce编程模型只能包含一个Map阶段和一个Reduce阶段,如果业务逻辑非常复杂,那就只能多个MapReduce程序,串行运行

我们通过一个具体的WordCount案例来进一步理解MapReduce

2. WordCount实践

2.1 新建模块hadoop,新增依赖配置

<dependencies>
   <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-client</artifactId>
       <version>3.3.4</version>
   </dependency>
</dependencies>

2.2 hadoop模块resouces目录下新建words.txt

shenjian suanfaxiaosheng
csdn wechat shenjian.online shenjian.online
wechat haotu369 suanfaxiaosheng csdn

2.3 新建WordCountMapper类

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> {

    private Text keyOut = new Text();
    private IntWritable valueOut = new IntWritable(1);

    @Override
    protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context) throws IOException, InterruptedException {
        // words.txt中的每一行均会调用次map方法
        String line = value.toString();
        String[] words = line.split(" ");
        for (String word : words) {
            keyOut.set(word);
            context.write(keyOut, valueOut);
        }
    }
}

2.4 新建WordCountReduce类

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

import java.io.IOException;

public class WordCountReduce extends Reducer<Text, IntWritable, Text, IntWritable> {

    private IntWritable valueOut = new IntWritable();

    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {
        // 接收map阶段过来的信息,进行统计
        int sum = 0;
        for (IntWritable value : values) {
            sum += value.get();
        }
        valueOut.set(sum);
        context.write(key, valueOut);
    }
}

2.5 新增WordCountDriver类

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

import java.io.IOException;

public class WordCountDriver {

    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "word count");
        job.setJarByClass(WordCountDriver.class);
        job.setMapperClass(WordCountMapper.class);
        job.setCombinerClass(WordCountReduce.class);
        job.setReducerClass(WordCountReduce.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

2.6 传参运行及结果查看

由于本地运行,写入绝对路径即可

E:\Java\blogCode\hadoop\src\main\resources\words.txt E:\Java\blogCode\hadoop\src\main\resources\words_ret.txt

结果如图所示

2.7 打包到集群上运行

  • 对于之前的hadoop集群部署,我们修改下配置已使得可以WebUI直接可以上传,datanode放开9864端口,hostname设置为datanode,其他节点同理设置namenode等,最后我们在电脑hosts中配置域名对应IP即可

最新可参考https://gitee.com/SJshenjian/blog-code/blob/master/src/main/java/online/shenjian/hadoop/docker-compose.yml

  datanode:
    ports:
      - 9864:9864
    hostname: datanode
  • 我们上传words.txt文件至目录/shenjian/input中

  • 在idea中package打包hadoop模块,目前集群支持jdk8,注意下版本,然后我们将打包好的jar包拷贝至namenode容器(当前容器id为b0f8a532e9452d51e5b49e97007ea087d36d887b99e2cd8f13bfb78802f4df7c)中
$ docker cp hadoop-1.0-SNAPSHOT.jar b0f8a532e9452d51e5b49e97007ea087d36d887b99e2cd8f13bfb78802f4df7c:/
  • 最后我们进入namenode容器中运行
# hadoop jar hadoop-1.0-SNAPSHOT.jar online/shenjian/hadoop/WordCountDriver /shenjian/input/ /shenjian/output


欢迎关注公众号算法小生第一时间获取最新文章

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法小生Đ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值