大数据之Hadoop生态圈中的Map Reduce学习(第五篇 )

大数据之MapReduce学习(简易见解)
前言
继我们上篇讲了HDFS的客户端操作之后,我们今天来分享一下Hadoop生态圈中第二个重要组成部分——MapReduce。

一、MapReduce入门
首先我们要知道MapReduce是在Hadoop生态圈中是个什么位置能做什么。

1.1MapReduce定义
MapReduce是一种分布式运算程序的编程模型,是用户开发“基于hadoop的数据分析应用”的核心框架,用于大规模数据集(大于1TB)的并行运算。
Mapreduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个hadoop集群上。

那么我们为什么要使用MapReduce呢?
1.2 MapReduce优缺点

1.2.1 MapReduce的优点
1)易于编程
它简单的实现一些接口,就可以完成一个分布式程序,这个分布式程序可以分布到大量廉价的PC机器上运行。也就是说你写一个分布式程序,跟写一个简单的串行程序是一模一样的。就是因为这个特点使得MapReduce编程变得非常流行。
2)良好的扩展性
当你的计算资源不能得到满足的时候,你可以通过简单的增加机器来扩展它的计算能力。
3)高容错性
MapReduce设计的初衷就是使程序能够部署在廉价的PC机器上,这就要求它具有很高的容错性。比如其中一台机器挂了,它可以把上面的计算任务转移到另外一个节点上运行,不至于这个任务运行失败,而且这个过程不需要人工参与,而完全是由Hadoop内部完成的。
4)适合PB级以上海量数据的离线处理
这里加粗的离线处理,说明它适合离线处理而不适合在线处理。比如像毫秒级别的返回一个结果,MapReduce很难做到。
1.2.2 MapReduce的缺点
MapReduce不擅长做实时计算、流式计算、DAG(有向图)计算。
1)实时计算。
MapReduce无法像Mysql一样,在毫秒或者秒级内返回结果。
2)流式计算。
流式计算的输入数据是动态的,而MapReduce的输入数据集是静态的,不能动态变化。这是因为MapReduce自身的设计特点决定了数据源必须是静态的。
3)DAG(有向图)计算。
多个应用程序存在依赖关系,后一个应用程序的输入为前一个的输出。在这种情况下,MapReduce并不是不能做,而是使用后,每个MapReduce作业的输出结果都会写入到磁盘,会造成大量的磁盘IO,导致性能非常的低下。
1.3 核心思想工作原理
MapReduce可以分成Map和Reduce两部分理解。
1.Map:映射过程,把一组数据按照某种Map函数映射成新的数据。

2.Reduce:归约过程,把若干组映射结果进行汇总并输出。

那么这个MapReduce编程模型究竟是怎么样的呢? 让我们来看一个实际应用的栗子吧。

栗子:

伐木出产品

假设我们这里现在有一个大规模的数据,看做一座座山,山上有一些树木(我们的数据)。在这座上上呢,都有红木、橡木、和樟木。我现在要去砍树加工成成品做成桌椅板凳家具等。山头即为我们HDFS上存储的block块。

我们可以把Reduce看做我们的加工厂,我们相对应的有红木加工厂、橡木加工厂、和樟木加工厂,这样送来的东西我们都可以通过工厂加工成家具(我们最后想要得到的数据)。

现在假设我们有三个伐木工,现在我们其中的计算程序看做是伐木工,让他们去砍树。就是把计算程序发送到存储数据block节点上,即为计算找数据。这也是我们大数据处理的原则之一。

好了,现在我们的每个伐木工已经从山上砍下来了许多的红木、橡木和樟木。那么我们为了提高工厂效率,我们是不是可以在伐木工砍完树后,对这些木头进行一个简答的处理做成桌面和桌腿然后再送往工厂,让工厂做个简单的加工就能出厂呢?就是这么个理。

现在我们的3个伐木工已经砍下了红木橡木樟木,然后现在对他们三个伐木工砍下来的树木进行个整理。总共分成三垛,第一垛是红木的汇总(包含一些成型的桌子,还有不成型的桌面以及桌腿),第二垛是橡木的汇总(包含一些成型的桌子,还有不成型的桌面以及桌腿),第三垛是樟木的汇总(包含一些成型的桌子,还有不成型的桌面以及桌腿)。

然后我们将这三垛材料通过shuffle分别传输给Reduce红木工厂、橡木工厂、樟木工厂。但是在运到工厂前我先让他们提前进行个组装,也就是merge。然后再传送给工厂进行一个简单组装形成我们的产品最后输出出去,也就是把我们的成品销售出去。

好了以上就是他的一个基本的工作原理,上图简单的阐明了map和reduce的两个过程或者作用,虽然不够严谨,但是足以提供一个大概的认知。

官方配图


1.4WordCount 案例实操

1)需求:在一堆给定的文本文件中统计输出每一个单词出现的总次数
2)数据准备:一个写有内容的txt文件。

那么我们下面进行一个实际操作一下,让我们更加深入直观方便的理解一下。
话不多说,打开我们的eclipse(我们之前配置过的eclipse)。

3)分析
照mapreduce编程规范,分别编写Mapper,Reducer,Job。

新建一个Map/Reduce project


然后在我们的src包里创建 mapper,reduce和job类(普通的类)
统计词频的MapReduce函数的核心代码非常简短,主要就是实现这两个函数。

首先编写mapper类

package com.sina.test;

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;
/* 
 * mapreduce程序中map端在读取数据的时候,默认每一次读一行  long string string int
 * 在mapreduce中原有的java类型是在数据传输中不能使用 ,需要使用其封装类  LongWritable 
 * context作用是连接map端和reduce端程序的连接点,输出的数据需要通道context写到磁盘中
*/
                        //            key键    value的类型     传输类型     传送过去值得类型
public class Mapper1 extends Mapper<LongWritable, Text, Text, IntWritable> {

    private final static IntWritable one=new IntWritable(1);
    private Text word=new Text();
    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String[] st=value.toString().split(" ");
        for (int i = 0; i < st.length; i++) {
            context.write(word, one);
        }
    }

}


然后编写Reducer类

package com.sina.test;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
//                                原本的类型,传输过来value的类型,传输的类型,设置value的类型                    
public class Reduce1 extends Reducer<Text, IntWritable, Text, IntWritable> {

    public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        // process values
        int sum=0;
        for (IntWritable  i: values) {
            sum+=i.get();
        }
        context.write(key, new IntWritable(sum));
    }

}


最后编写驱动类

package com.sina.test;

import java.io.IOException;

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.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class Job1 {
    
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        //设置用户名        环境变量
        System.setProperty("HADOOP_USER_NAME", "root");
        //创建配置对象
        Configuration conf = new Configuration();
        //设置配置对象  namenode
        conf.set("dfs.defaultFS", "hdfs://192.168.***.***.9000");
        Job job = Job.getInstance(conf);
        //引号里的是进程名 可以随便起
        job.setJobName("wc2Job");
        job.setJarByClass(Job1.class);
        job.setMapperClass(Mapper1.class);
        job.setReducerClass(Reduce1.class);
        //这里是传送过来的key value
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);
        
        //设置需要计算的输入文件路径
        //输入路径
        FileInputFormat.setInputPaths(job, new Path("hdfs://192.168.***.***:9000/user/root/haha.txt"));
        //输出显示到的路径
        FileOutputFormat.setOutputPath(job, new Path("hdfs://192.168.***.***:9000/user/a/"));
        //设置权限
        boolean zt = job.waitForCompletion(true);
        if (zt) {
            System.out.println("执行成功");
        }
    }
}


最后控制台打印出 “执行成功” 即为操作成功。然后我们在目录下查看下我们的文件,以及统计次数


                             —————END—————
--------------------- 
作者:夜、那么美จุ๊บ 
来源:CSDN 
原文:https://blog.csdn.net/adamaaron/article/details/91972980 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值