mr执行原理

  • mapreduce思想 先分再合 分而治之
    • map:负责分,所谓的分指的是把大的复杂的任务划分成小的任务,然后并行处理提高效率
      (如果任务不可以拆分或者任务内部存在着依赖关系 这样不适合分而至之)
    • reduce:负责合 ,所谓的合指的是把上步分成的小任务结果聚合成最终的结果
      两步加起来就是mapreduce思想的体现。
  • hadoop mapreduce 设计构思
    • 如何解决大数据的高效计算问题:使用先分再合 分而治之的思想
    • 抽象出map reduce的编程模型:在mr框架中 数据都是以kv键值对形式的存在
    • 统一封装底层架构逻辑 用户负责做什么 程序负责怎么做 两者结合构成mr程序

所谓的编程框架或者说编程规范指的是:只要按照别人的规范套路来 就可以实现与之对应的功能


在这里插入图片描述

  • mapreduc编程规范和架构构思

  • 从代码层面看
    类1----->继承Mapper :负责map阶段具体业务逻辑
    类2----->继承reducer :负责reduce阶段具体的业务逻辑
    类3----->含有main方法的类 程序运行的主类 入口(负责相关参数的指定)

    把上面3个类打成jar包 就构成了一个mr的程序。
    
  • 从运行层面看:
    MapTask:负责处理map阶段的业务逻辑 也就是上述的类1
    ReduceTask:负责处理Reduce阶段的业务逻辑 也就是上述的类2
    MRAppMaster:mr程序的管家 负责程序内的调度协调处理 监督执行


在这里插入图片描述

  • mr案例:wordcount

  • 需求描述:统计指定文件中每个单词出现的总次数
    hadoop allen hadoop
    allen hello hadoop

    hadoop 2
    allen 3
    
  • 处理思路

    • map :把接受的数据变成<单词,1>这样形式的键值对
    • reduce:把上个阶段单词相同的键值对进行累加 得出最终结果

  • Mapper中的重要方法
    setup 初始化方法 maptask执行前执行一次 且执行一次
    map map阶段处理具体业务逻辑的方法
    cleanup 扫尾化方法 maptask执行结束前执行一次 且执行一次
  • Reducer中的重要方法
    setup 初始化方法 reducetask执行前执行一次 且执行一次
    map reduce阶段处理具体业务逻辑的方法
    cleanup 扫尾化方法 reducetask执行结束前执行一次 且执行一次

  • mr程序的执行模式
    • 集群模式
      指的把程序打成jar包提交给yarn集群运行 由yanr分配运算资源
      这种模式是mr程序在正式环境中运行的模式
      这种模式下mr程序才是分布式计算的程序
      这种模式下数据位于hdfs文件系统之上。
    • 本地模式
      指的是在本地以线程模型mr运行的环境 由本地机器提供运算资源
      这种模式是开发环境使用
      这种模式程序是单机版的 不是分布式的程序
      这种模式通常数据可以位于本地文件系统
      至于mr程序到底是是本地模式还是集群模式,取决于配置
      mapreduce.framework.name 是local 还有yarn
      如果不写会尝试加载运行程序所在机器的环境变量 查看具体配置。

  • 关于mr的输入
    • 如果指向的是一个文件 那么就处理这个文件
    • 如果指向的是一个文件夹(目录),那么就处理这个文件夹下所有的文件
  • mapreduce程序 maptask个数由哪些因数决定
    文件的个数
    文件的大小
    切片的大小
  • reducetask个数是由哪些因数决定
    默认是1
    是由设置决定
    job.setNumReduceTasks(N)
    N为几 个数就是几

  • mapreduce编程技巧
    在mr中 要牢牢把握住key是什么 因为key有很多默认的属性存在
    排序 -----> key的字典序
    分区 -----> key哈希 % reducetask
    分组 -----> key相同的分为一组
  • 在mr中 可以把上一个mr的输出直接作为下一个mr的输入
    程序可以自动识别里面那些是真实数据所在的文件。

  • 输出数据文件有多个------>reducetask至少两个及以上------>默认是一个,如何设置多个?------>job.setnumReducetasks(N)----->涉及到数据的分区-------->分区的规则------->默认分区规则---->key的哈希值对reducetaks个数取模-------->默认分区规则满足业务需求吗?----->如果满足,直接用----->如果不满足------>自定义分区规则------>如何自定义分区呢?-------->接下来认真听课------>如何使得自定义分区生效
    首先写一个类 继承Partitioner

    重新里面的 getPartition  该方法返回值是几  数据的分区标号就是几
    
    最后需要在代码中进行设置:
    job.setPartitionerClass(ProvincePartitioner.class);
    
  • 自定义分组
    OrderBean(orderId userId ItemID name price)
    00001 1 pd_001 apple 13.48
    00002 1 pd_002 apple2 13.48
    00003 2 pd_004 apple3 13.48
    00004 1 pd_006 apple4 13.48
    需求:统计每个用户的订单总金额是多少?
    方式一:
    <userid ,price>
    方式二:
    <OrderBean,xxxx>
    public class GroupComparator extends WritableComparator{

        public GroupComparator() {
            super(OrderBean.class,true);
        }
    
        @Override
        public int compare(WritableComparable a, WritableComparable b) {
    
            OrderBean o1 = (OrderBean) a;
            OrderBean o2 = (OrderBean) b;
            
            
            return o1.getuserID().compareTo(o2.getUserID());
        }
    }
    

    需要在代码中进行设置
    job.setGroupingComparatorClass(GroupComparator.class);


猜你喜欢

转载自blog.csdn.net/weixin_44654375/article/details/87893087
MR