MapReduce基础

MapReduce

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

为什么需要MapReduce

  • 海量数据单机处理,硬件资源受限,所以无法胜任(硬盘读写速度、CPU处理速度等)
  • 单机版阔成分布式版,增加程序复杂度和开发难度
  • 为了提高开发效率,将分布式程序中的公共功能封装成框架,让开发人员可以将精力集中于业务逻辑。

MapReduce程序演示

  • wordcount程序
  • 开启HDFS和YARN
  • 将元数据上传到HDFS
  • 运行命令:hadoop jar hadoop-mapreduce-examples-2.6.5.jar wordcount 输入路径 输出路径

MapReduce 示例编写及编程规范

编码规范

Mapper
  • 1.继承Mapper类
  • 2.输入数据是<key,value>对形式(kv的类型可以自定义)
  • 3.输出数据是<key,value>对形式(kv的类型可以自定义)
  • 4.业务逻辑是写在map()方法中
  • 5.MapTask进程对每一个<k,v>调用一次map()方法
Reduce
  • 1.继承Reduce类
  • 2.输入数据类型对应Mapper的输出数据类型,也是<key,value>对形式
  • 3.输出数据是<key,value>对形式(kv的类型可以自定义)
  • 4.业务逻辑是写在reduce()方法中
  • 5.MapTask进程对每一组相同的k的<k,v>调用一次reduce()方法
Driver

(提交运行MR程序的客户端),配置程序的运行信息,提交job对象

WordCount 示例程序编写

WordCount 的业务逻辑:
MapTask阶段
  • 处理每个数据分块的单词统计分析,思路是将每一行文本拆分成一个个的单词,每遇到一个单词则把其转换成一个 key-value 对,比如单词 hello,就转换成<’hello’,1>发送给 ReduceTask 去汇总。
ReduceTask阶段
  • 将接收 MapTask 的结果,按照 key 对 value 做汇总计数
  • 流程图
    在这里插入图片描述
WordCount 程序编写:

Map端: 将每一行文本拆分为一个个单词,每遇到一个单词则把其转换成一个key-value对
Reduce端: 接收Map端的结果,按照key对value做汇总计数
Job端: 程序的主入口,相当于YARN集群的客户端

MapReduce 程序运行模式

本地运行模式:

在这里插入图片描述

集群运行模式:

在这里插入图片描述

        //创建配置信息类
        Configuration conf=new Configuration();
        conf.set("fs.defaultFS","hdfs://master:9000");
        conf.set("mapreduce.framework.name","yarn");
        conf.set("yarn.resourcemanage.hostname","master");
        System.setProperty("HADOOP_USER_NAME","theone");

        //新建一个Job任务
        Job job=Job.getInstance(conf);
        //指定jar包的路径
        job.setJarByClass(WordCountDemo.class);
        //指定Mapper类和Reducer类
        job.setMapperClass(WordCountMapper.class);
        //指定combiner
        job.setCombinerClass(WordCountReducer.class);
        job.setReducerClass(WordCountReducer.class);

        //指定maptask的key-value对的输出类型
        //job.setMapOutputKeyClass(Text.class);
        //job.setMapOutputValueClass(IntWritable.class);

        //指定reducetask的key-value对的输出类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        //指定mr程序输入输出数据路径
        Path inpath=new Path("/mr/wordcount/input");
        Path outpath=new Path("/mr/wordcount/output");
        //获取fs对象
        FileSystem fs = FileSystem.get(conf);
        if (fs.exists(outpath)){
            //存在则删除输出路径
            fs.delete(outpath,true);
        }

        FileInputFormat.setInputPaths(job, inpath);
        FileOutputFormat.setOutputPath(job, outpath);

        //提交任务job,等待mr程序运行完成打印反馈信息
        boolean waitForCompletion = job.waitForCompletion(true);
        // 退出程序
        System.exit(waitForCompletion?0:1);

MapReduce 三大组件(一):Combiner

  • 什么是Combiner?
什么是Combiner?
  • 作用: 在MapTask之后给MapTask的结果进行局部汇总,以减轻ReduceTask的计算负载,减少网络传输
  • 实现: 本地key的聚合,对map输出的key排序,value进行迭代,有本地Reduce之称
数据格式的转换:

map:(k1,v1)–>list(k2,v2)
combiner:(k2,list(v2))–>list(k3,v3)
reduce:(k3,list(v3))–>list(k4,v4)

  • 具体实现步骤:
    (1)自定义一个Combiner继承Reducer,重写reduce方法
    (2)在job中设置:job.setCombinerClass(xxx.class)
  • 具体代码实现
    和reduce端的代码一致,在job中设置Cominer类
注意事项
  • (1)运行位置
    Combiner是在每一个MapTask所在的节点运行
    recuder是接收全局所有Mapper的输出结果
  • (2)Combiner 的输出 KV 跟 Reducer 的输入 KV 类型相对应
  • (3)Combiner 使用的原则是:有或没有都不能影响业务逻辑,都不能影响最终结果。
  • (4)适用场景:汇总统计;不适用场景:求平均数。适用于Reduce的输入key/value与输出key/value类型完全一致情况

MapReduce 程序的核心运行机制

1-结构

  • MRAppMaster(MapReduce Application Master)负责整个程序的过程调度及状态协调
  • YarnChild
    MapTask:负责Map阶段的整个数据处理流程,阶段并发任务
    ReduceTask:负责Reduce阶段的整个数据处理流程,阶段汇总任务
    MapTask和ReduceTask不在同一个Yarnchild进程中

2-MR程序的运行流程

  • (1)一个 MR 程序启动的时候,最先启动的是 MRAppMaster, MRAppMaster 启动后根据本次 job 的描述信息,计算出需要的 MapTask 实例数量,然后向集群申请机器启动相应数量的 MapTask 进程;
  • (2)MapTask 进程启动之后,根据给定的数据切片(哪个文件的哪个偏移量范围)范围进行数据处理,主体流程为:
    1,利用客户指定的 InputFormat 来获取 RecordReader 读取数据,形成输入 KV 对
    2,将输入 KV 对传递给客户定义的 map()方法,做逻辑运算,并将 map()方法输出的 KV 对收集到缓存
    3,将缓存中的 KV 对按照 K 分区排序后不断溢写到磁盘文件
  • (3)MRAppMaster 监控到所有 MapTask 进程任务完成之后(真实情况是,某些 MapTask 进程处理完成后,就会开始启动 ReduceTask 去已完成的 MapTask 处 fetch 数据),会根据客户指定的参数启动相应数量的 ReduceTask 进程,并告知 ReduceTask 进程要处理的数据范围(数据分区);
  • (4)ReduceTask 进程启动之后,根据 MRAppMaster 告知的待处理数据所在位置,从若干台 MapTask 运行所在机器上获取到若干个 MapTask 输出结果文件,并在本地进行重新归并排序,然后按照相同 key 的 KV 为一个组,调用客户定义的 reduce() 方法进行逻辑运算,并收集运算输出的结果 KV,然后调用客户指定的 OutputFormat 将结果数据输出到外部存储。

MapTask 并行度决定机制

  • 问题场景
    MapTask 并行度决定 Map 阶段的任务处理并发度,进而影响到整个 Job 的处理速度。那么, MapTask 并行实例是否越多越好呢?其并行度又是如何决定呢?
  • 一个 Job 的 Map 阶段并行度由客户端在提交 Job 时决定, 客户端对 Map 阶段并行度的规划的基本逻辑为:
    将待处理数据执行逻辑切片(即按照一个特定切片大小,将待处理数据划分成逻辑上的多个 split),然后每一个 split 分配一个 MapTask 并行实例处理

FileInputFormat 切片机制

  • 默认切片机制
    1.简单地按照文件的内容长度进行切片
    2.切片大小,默认等于 block 大小
    3.切片时不考虑数据集整体,而是逐个针对每一个文件单独切片

  • 切片大小参数配置
    切片大小计算公式:

    long splitSize = computeSplitSize(Math.max(minSize, Math.min(maxSize, blockSize)))

    主要参数:

    blocksize: 默认是 128M,可通过 dfs.blocksize 修改
    minSize: 默认是 1,可通过 mapreduce.input.fileinputformat.split.minsize 修改
    maxsize: 默认是 Long.MaxValue,可通过mapreduce.input.fileinputformat.split.maxsize 修改

ReduceTask 并行度决定机制

  • ReduceTask 数量可以直接手动设置
    job.setNumReduceTasks(4);
    如果数据分布不均匀,就有可能在 reduce 阶段产生数据倾斜。
  • 注意:ReduceTask 数量并不是任意设置,还要考虑业务逻辑需求,有些情况下,需要计算全局汇总结果,就只能有 1 个 ReduceTask。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值