MapReduce详解

MapReduce 执行的过程中会有三种进程:


    1. MRAppMaster:负责整个任务的调度和协调
    2. MapTask:负责 map 阶段的任务处理
    3. ReduceTask:负责 reduce 阶段的任务处理


当我们提交任务:hadoop jar xxxx.jar /input /output
    首先启动 MRAppMaster 进程,MRAppMaster 根据任务的描述(inputformat)计算出需要多少个 MapTask,然后向集群申请资源,启动对应的 MapTask 进程
    MapTask 启动后读取对应的数据,生成 kv 对,对每组 kv 对调用 map() 进行处理,输出 kv 对到硬盘
    MRAppMaster 监控每个 MapTask 都完成任务后,启动客户端指定数量的 ReduceTask:job.setNumReduceTasks(),然后指定每个 ReduceTask 获取数据的范围

    ReduceTask 启动后回去对应的 MapTask 所在的硬盘上获取 MapTask 输出的 kv 对,ReduceTask 从若干台机器上获取 kv 对后会进行聚合操作,k 相同的 v 合并在一起形成新的 kv 对,然后分别调用 reduce 方法进行处理,处理结果通过客户端执行 ouputformat 进行输出


1. MapTask 个数由 split(切片) 个数决定:
   split 是逻辑概念,从逻辑上对文件进行切分,并不会对文件的实际保存产生影响。
   默认一个 split 的大小是 block 的大小:有几个 block 就有几个 split,就有几个 map
       eg:200M = 2 block = 2 split = 2 map


   split 是针对于每个文件独立计算的
           200M + 30M = 3 block = 3 split = 3 map
   每个 MapTask 从切片指定的位置读数据


2. MapTask 的并行数主要依赖下面三项:
   1. 计算的硬件配置
   2. 任务的类型:cpu 密集型(以计算为主)还是 io 密集型(以读写为主)
   3. 任务的数量


   如果 MapTask 比较多,就是分批次执行,一批执行完毕,再执行下一批






3. MapTask 保存数据到硬盘:
   MapTask 把输出的 kv 对会先放在内存中的一块缓冲区内(默认是 100M),当达到指定数量(80%)时一次性写入硬盘,在写入硬盘的过程中,新的 kv 可以写入剩余的空间,这个操作叫做:溢写


   写数据的时候会进行 partioner(分区)的操作:决定了这个 kv 交给哪个 reduce 进行处理
       通常是:(key.hashCode() & Integer.MAX_VALUE) % numReduceTasks 个数,计算结果就是对应的 reduce 的编号
                      key 相同的 hashcode 都相同,计算出来的 reduce 编号也是相同的,所以能够在同一个 reduce 上进行聚合
   
   还会进行 sort(排序)操作:按照 key 进行排序


   溢写会产生好多小文件,最终还要合并为一个大文件


4. 如果有 combiner,那么溢写后执行


5. ReduceTask 从各个 MapTask 所有在机器上读取数据了,读完所有的数据以后会进行归并排序和聚合形成新的 kv 对文件


6. ReduceTask 处理生成的 kv


7. shuffle:map 传递数据给 reduce 的流程阶段
       Map 端:分区,排序
       Reduce 端:排序,聚合




写代码的时候先有 map 和 reduce,后有 combiner
    必须遵守的原则:map 的输出是 reduce 的输入
        combiner 的输入输出是一样的:map 的输出/reduce 的输入



通过 job.setNumReduceTasks() 方法设置 reduce 的个数,reduce 的个数决定了 outputDir 中 part-r-00000 的个数,每个 reduce 输出一个 part 文件


自定义分区,需要继承 Partitioner,实现 getPartition 方法,输出 reduce 编号
然后 job.setPartitionerClass(); 设置就可以了

自定义分区 + 多个 reduce 可以把数据按要求输出到多个文件中,方便阅读


设置 reduce 端,key 聚合的规则
job.setGroupingComparatorClass()

设置 reduce 端,key 排序的规则
job.setSortComparatorClass()

上述的两个功能,都要通过继承 WritableComparator 类重写 compare 方法完成
    需要重写构造方法,指定 key 的类型

全排序:
    reduce 内的数据有顺序,reduce 之间也有顺序
        1. 一个 reduce,效率不高
        2. 通过 partitioner 实现:每个 reduce 处理不同区间的值,可能会出现数据倾斜
           数据倾斜:某些 reduce 处理了大部分的数据

        3. 使用随机抽样的方式划分区间































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值