Map和Reduce任务的优化

本文介绍MapReduce计算模型的六大优化策略:任务调度、数据预处理、合理设置InputSplit大小、调整map/reduce任务数量、利用combine函数及压缩技术,帮助提升大数据处理效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编程总是围绕着两个问题:“如何完成这个任务”和“如何能让程序运行得更快”

因此,相对应的MapReduce计算模型的优化也就集中在两个方面:一是计算性能方面的优化;二是I/O操作方面的优化

1、任务调度

两个方面的优化:一是计算方面:Hadoop总会先将任务分配给空闲的机器,使所有的任务能公平地分享系统资源;二是I/O方面:Hadoop会尽量将map任务分配给InputSplit所在的机器,以减少网络I/O的消耗。(分配的就近原则)

2、数据预处理和InputSplit的大小

2.1.原因:MapReduce擅长处理少量的大数据,而在处理大量的小数据时,性能要逊色很多。

2.2.优化措施:在提交MapReduce任务之前可以对数据进行一次预处理,将数据合并以提高执行效率(很有效)。
进一步优化:可以考虑map任务的运行时间,当一个map任务只需要运行几秒钟就可以结束时,就需要考虑是否应该给它分配更多的数据了。(一分钟左右比较合适)——设置方法:可通过设置map的输入数据大小来调节map的运行时间。A、合理地设置block块的大小(在FileInputFormat中,hadoop会在处理每个block后将其作为一个InputSplit);B、合理地设置map任务的数量。

3、map和reduce任务的数量

3.1.定义:map任务槽和reduce任务槽就是这个集群能够同时运行的map/reduce任务的最大数量。(比如在一个具有1200台机器的集群中,设置每台机器最多可以同时运行10个map和5个reduce,那么这个集群的map任务槽就是12000,reduce任务槽是6000。)

3.2.设置reduce数量

(map数量设置主要考虑它的运行时间)

设置reduce的数量时只需要参考任务槽的设置。一般来说reduce任务的数量应该是reduce任务槽的0.95倍或是1.75倍。

0.95倍易于找到空闲机器处理失败的任务。1.75则可以使负载更加均衡(执行速度快的机器可以获得更多的任务),以提高任务的处理速度。

4、combine函数
4.1.作用:用于在本地合并数据。例如,在单词计数中,combine函数先计算出在这个block中某个单词的个数,再传输给reduce。如下图:

没有使用combine函数

使用了combine函数


4.2.使用方法:job.setcombineClass(combine.class);
在WordCount程序中,可以指定reduce函数为combine函数
job.setReduceClass(Reduce.class)

5、压缩
编写MapReduce程序时,可以选择对map的输出和最终的输出结果进行压缩(可自行选择压缩方式)。

#当map的中间输出很大时,对其进行压缩可以有效地减少网络上的数据传输量。

#对最终结果的压缩虽然可以减少数据写入HDFS的时间,但是也会对读取产生一定的影响,因此要根据时间情况来选择。
6、自定义comparator(自定义数据类型以实现更复杂的目的)
比如:k-means算法(基础的聚类算法)。

 

本篇博文内容主要来自《Hadoop实战》一书。

 

 

### Map任务Reduce任务的概念 在分布式计算框架中,Map任务Reduce任务是核心组件之一。这些概念源自函数式编程领域,在Hadoop其他类似的框架中得到了广泛应用。 #### Map任务的工作原理 Map任务负责处理输入数据并将其转换成键值对的形式。具体来说: - 输入的数据被分割成多个分片(split),每个分片由一个单独的Mapper实例来处理。 - Mapper读取分片中的记录,并通过用户定义的映射逻辑将每条记录转化为若干个`<key,value>`形式的中间结果[^2]。 例如,在单词计数的例子中,对于每一行文本作为输入,map操作会输出形如`(word, 1)`这样的键值对集合。 ```java public class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); private Text word = new Text(); public void map(Object key, Text value, Context context) throws IOException, InterruptedException { StringTokenizer itr = new StringTokenizer(value.toString()); while (itr.hasMoreTokens()) { word.set(itr.nextToken()); context.write(word, one); // 输出(key-value): ("hello", 1), ("world", 1) } } } ``` #### Reduce任务的工作原理 完成映射阶段之后,所有的中间键值对会被收集起来并通过网络传输给Reducer节点。Reducer的任务是对具有相同键的所有值执行聚合运算或其他类型的汇总操作。 - 来自不同Mapper产生的相同Key对应的Value列表会被发送到同一个Reducer上进行进一步加工。 - Reducer接收来自各个Mapper传来的数据流,按照相同的Key组合在一起形成新的键值对集合作为最终输出的一部分。 继续上面提到的词频统计案例,reduce过程会对所有带有特定词语作为Key的数值求得到该词在整个文档集中出现次数的结果。 ```java public class IntSumReducer extends Reducer<Text,IntWritable,Text,IntWritable> { private IntWritable result = new IntWritable(); @Override protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritable val : values) { sum += val.get(); // 对于("hello",[1,1]) -> 计算总=2 } result.set(sum); context.write(key, result); // 输出(hello, 2) } } ``` ### 应用场景 MapReduce非常适合用于大规模数据分析任务,特别是当涉及到大量结构化或半结构化的离线批处理作业时表现尤为出色。典型的应用包括但不限于: - **日志分析**:解析Web服务器的日志文件以提取访问模式、错误报告等有用信息; - **搜索引擎索引构建**:从网页抓取的内容创建倒排索引来加速查询响应时间; - **机器学习模型训练**:利用海量样本数据来进行参数估计与优化算法迭代更新;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值