Hadoop三大组件之MapReduce

一、MapReduce的概述
MapReduce定义

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

二、MapReduer的优缺点

2.1 MapReduce的优点

1. MapReduce易于编程
	它简单的实现一些接口,就可以完成一个分布式程序,这个分布式程序可
 以分布到大量廉价的PC机器上运行。也就是说你写一个分布式程序,跟写
 -一个简单的串行程序是一模一样的。 就是因为这个特点使得MapReduce编
 程变得非常流行。

2.良好的扩展性
	当你的计算资源不能得到满足的时候,你可以通过简单的增加机器来扩展
 它的计算能力。
 
3.高容错性
	MapReduce设计的初衷就是使程序能够部署在廉价的PC机器上,这就要求
  它具有很高的容错性。比如其中一台机器挂了,它可以把上面的计算任务
 转移到另外- -个节点上运行,不至于这个任务运行失败,而且这个过程不
 需要人工参与,而完全是由Hadoop内部完成的。
 
4.适合PB级以上海量数据的离线处理
	可以实现上千台服务器集群并发工作,提供数据处理能力。

2.2MapReduce的缺点

1.不擅长实时计算
	MapReduce无法像MySQL-样,在毫秒或者秒级内返回结果。
2.不擅长流式计算
	流式计算的输入数据是动态的,而MapReduce的输, 入数据集是静态的,不能
 动态变化。这是因为MapReduce自身的设计特点决定了数据源必须是静态的。
3.不擅长DAG (有向图)计算
	多个应用程序存在依赖关系,-个应用程序的输入为前一个的输出。在
 这种情况下,MapReduce并不是不能做,而是使用后,每个MapReduce作业
 的输出结果都会写入到磁盘,会造成大量的磁盘IO,导致性能非常的低下。

三、MapReduce的进程

 一个完整的MapReduce程序在分布式运行时有三类实例进程:
	1) MrAppMaster: 负责整个程序的过程调度及状态协调。
	2) MapTask:负责Map阶段的整个数据处理流程。
	3) ReduceTask:负责Reduce阶段的整 个数据处理流程。

四、MapReduce的序列化
4.1序列化的感念

1.什么是序列化
	序列化就是把内存中的对象,转换成字节序列(或其他数据传输协议)以便
 于存储到磁盘(持久化)和网络传输。
 反序列化就是将收到字节序列(或其他数据传输协议)或者是磁盘的持久化
 数据,转换成内存中的对象。
2。为什么要序列化 
	-般来说,"活的” 对象只生存在内存里,关机断电就没有了。而且“活的”
 对象只能由本地的进程使用,不能被发送到网络上的另外一台计算机。然而序
 列化可以存储“活的”对象,可以将“活的”对象发送到远程计算机。

4.2序列化时应该注意事项

	1.在企业开发中往往常用的基本序列化类型不能满足所有需求,比如在Hadoop框架内部传递一个bean对象,
那么该对象就需要实现序列化接口(Writable)。
	2.反序列化时,需要反射调用空参构造函数,所以必须有空参构造
		public Bean(){}
	3.重写序列化方法
		public void write(DataOutput out) throws IOException {
			out.writeLong(upFlow);
			out.writeLong(downFlow);
			out.writeLong(sumFlow);	
		}
	4.重写反序列化方法
		public void readFields(DataInput in) throws IOException {
			upFlow = in.readLong();
			downFlow = in.readLong();
			sumFlow = in.readLong();
		}

4.2序列化实操

第一步  1.创建一个bean类 封装变量 用来存放需要提取出的数据
	2.实现getset方法、无参构造、toString方法 和 setXXXdata方法此方法用来赋值
	3.实现Writable接口 序列化接口
	4.重写Writable接口的方法

第二步  1.创建一个mapper类 并继承mapper方法并且加上泛型
	2.重写map方法 封装变量来获取需要的数据 和调用Bean中的赋值方法
	3.使用toS听方法给传进来的数据转换为字符
	4.然后用空格切分装进属组
	5.遍历属组并使用Long.pareseLong(split[split.length-*]),根据空格切分后获取需要的第几列数据
	6.context输出

第三步	1.创建一个Reducer类 继承Reducer方法并加上泛型(reducer类的泛型就是Mapper输出的泛型)
	2.重写reducer方法
	3.封装变量用来调用bean中的方法
	4.创建变量来接受处理好的数据,并遍历数据将想要的数据赋值到变量
	5.调用bean中的赋值方法进行赋值
	6.context输出

第四步  1.创建驱动类Driver 用pvsm来召唤main方法
	2.获取配置文件和job对象
	3.设置jar
	4.设置mapper和reducer类
	5.设置mapper和reducer类的key value 数据类型
	6.自定义分区 Partitioner
	7.设置文件输出入的路径
	8.设置提交反馈

第五步  1.创建Partitioner类 继承partitioner方法 并添加泛型
	2.重写Partitioner方法
	3.将数据转为字符
	4.switch substring(**case 来获取几到几列

public class PhoneBean implements Writable {
    //    总台数,总销售额
    private Long sumPhone; //总台数
    private Long price; //商品价格
    private Long totalSales;//总销售额
    public PhoneBean() {
    }
    public void setPhoneData(Long sumPhone,Long price){
        this.sumPhone = sumPhone;
        this.price = price;
        this.totalSales = sumPhone*price;
    }

    @Override
    public String toString() {
        return sumPhone + "\t" + totalSales + "\t" ;
    }

    public Long getSumPhone() {
        return sumPhone;
    }
    
    public void setSumPhone(Long sumPhone) {
        this.sumPhone = sumPhone;
    }
    
    public Long getPrice() {
        return price;
    }

    public void setPrice(Long price) {
        this.price = price;
    }

    public Long getTotalSales() {
        return totalSales;
    }

    public void setTotalSales(Long totalSales) {
        this.totalSales = totalSales;
    }



    /**
     * hadoop的序列化方法
     * @param dataOutput
     * @throws IOException
     */
    public void write(DataOutput dataOutput) throws IOException {
        dataOutput.writeLong(sumPhone);
        dataOutput.writeLong(totalSales);

    }

    public void readFields(DataInput dataInput) throws IOException {
        sumPhone = dataInput.readLong();
        totalSales = dataInput.readLong();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值