- mapreduce思想 先分再合 分而治之
- map:负责分,所谓的分指的是把大的复杂的任务划分成小的任务,然后并行处理提高效率
(如果任务不可以拆分或者任务内部存在着依赖关系 这样不适合分而至之) - reduce:负责合 ,所谓的合指的是把上步分成的小任务结果聚合成最终的结果
两步加起来就是mapreduce思想的体现。
- map:负责分,所谓的分指的是把大的复杂的任务划分成小的任务,然后并行处理提高效率
- 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 hadoophadoop 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);