reduce的数目到底和哪些因素有关
1、我们知道map的数量和文件数、文件大小、块大小、以及split大小有关,而reduce的数量跟哪些因素有关呢?
设置mapred.tasktracker.reduce.tasks.maximum的大小可以决定单个tasktracker一次性启动reduce的数目,但是不能决定总的reduce数目。
conf.setNumReduceTasks(4);JobConf对象的这个方法可以用来设定总的reduce的数目,看下Job Counters的统计:
- Job Counters
- Data-local map tasks=2
- Total time spent by all maps waiting after reserving slots (ms)=0
- Total time spent by all reduces waiting after reserving slots (ms)=0
- SLOTS_MILLIS_MAPS=10695
- SLOTS_MILLIS_REDUCES=29502
- Launched map tasks=2
- Launched reduce tasks=4
确实启动了4个reduce:看下输出:
- diegoball@diegoball:~/IdeaProjects/test/build/classes$ hadoop fs -ls /user/diegoball/join_ou1123
- 11/03/25 15:28:45 INFO security.Groups: Group mapping impl=org.apache.hadoop.security.ShellBasedUnixGroupsMapping; cacheTimeout=300000
- 11/03/25 15:28:45 WARN conf.Configuration: mapred.task.id is deprecated. Instead, use mapreduce.task.attempt.id
- Found 5 items
- -rw-r--r-- 1 diegoball supergroup 0 2011-03-25 15:28 /user/diegoball/join_ou1123/_SUCCESS
- -rw-r--r-- 1 diegoball supergroup 124 2011-03-25 15:27 /user/diegoball/join_ou1123/part-00000
- -rw-r--r-- 1 diegoball supergroup 0 2011-03-25 15:27 /user/diegoball/join_ou1123/part-00001
- -rw-r--r-- 1 diegoball supergroup 214 2011-03-25 15:28 /user/diegoball/join_ou1123/part-00002
- -rw-r--r-- 1 diegoball supergroup 0 2011-03-25 15:28 /user/diegoball/join_ou1123/part-00003
只有2个reduce在干活。为什么呢?
shuffle的过程,需要根据key的值决定将这条<K,V> (map的输出),送到哪一个reduce中去。送到哪一个reduce中去靠调用默认的org.apache.hadoop.mapred.lib.HashPartitioner的getPartition()方法来实现。
HashPartitioner类:
- package org.apache.hadoop.mapred.lib;
- import org.apache.hadoop.classification.InterfaceAudience;
- import org.apache.hadoop.classification.InterfaceStability;
- import org.apache.hadoop.mapred.Partitioner;
- import org.apache.hadoop.mapred.JobConf;
- /** Partition keys by their {@link Object#hashCode()}.
- */
- @InterfaceAudience.Public
- @InterfaceStability.Stable
- public class HashPartitioner<K2, V2> implements Partitioner<K2, V2> {
- public void configure(JobConf job) {}
- /** Use {@link Object#hashCode()} to partition. */
- public int getPartition(K2 key, V2 value,
- int numReduceTasks) {
- return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
- }
- }
numReduceTasks的值在JobConf中可以设置。默认的是1:显然太小。
这也是为什么默认的设置中总启动一个reduce的原因。
返回与运算的结果和numReduceTasks求余。
Mapreduce根据这个返回结果决定将这条<K,V>,送到哪一个reduce中去。
key传入的是LongWritable类型,看下这个LongWritable类的hashcode()方法:
- public int hashCode() {
- return (int)value;
- }
简简单单的返回了原值的整型值。
因为getPartition(K2 key, V2 value,int numReduceTask)返回的结果只有2个不同的值,所以最终只有2个reduce在干活。
HashPartitioner是默认的partition类,我们也可以自定义partition类 :
- package com.alipay.dw.test;
- import org.apache.hadoop.io.IntWritable;
- import org.apache.hadoop.mapred.JobConf;
- import org.apache.hadoop.mapred.Partitioner;
- /**
- * Created by IntelliJ IDEA.
- * User: diegoball
- * Date: 11-3-10
- * Time: 下午5:26
- * To change this template use File | Settings | File Templates.
- */
- public class MyPartitioner implements Partitioner<IntWritable, IntWritable> {
- public int getPartition(IntWritable key, IntWritable value, int numPartitions) {
- /* Pretty ugly hard coded partitioning function. Don't do that in practice, it is just for the sake of understanding. */
- int nbOccurences = key.get();
- if (nbOccurences > 20051210)
- return 0;
- else
- return 1;
- }
- public void configure(JobConf arg0) {
- }
- }
仅仅需要覆盖getPartition()方法就OK。通过:
conf.setPartitionerClass(MyPartitioner.class);
可以设置自定义的partition类。
同样由于之返回2个不同的值0,1,不管conf.setNumReduceTasks(4);设置多少个reduce,也同样只会有2个reduce在干活。
由于每个reduce的输出key都是经过排序的,上述自定义的Partitioner还可以达到排序结果集的目的:
- 11/03/25 15:24:49 WARN conf.Configuration: mapred.task.id is deprecated. Instead, use mapreduce.task.attempt.id
- Found 5 items
- -rw-r--r-- 1 diegoball supergroup 0 2011-03-25 15:23 /user/diegoball/opt.del/_SUCCESS
- -rw-r--r-- 1 diegoball supergroup 24546 2011-03-25 15:23 /user/diegoball/opt.del/part-00000
- -rw-r--r-- 1 diegoball supergroup 10241 2011-03-25 15:23 /user/diegoball/opt.del/part-00001
- -rw-r--r-- 1 diegoball supergroup 0 2011-03-25 15:23 /user/diegoball/opt.del/part-00002
- -rw-r--r-- 1 diegoball supergroup 0 2011-03-25 15:23 /user/diegoball/opt.del/part-00003
part-00000和part-00001是这2个reduce的输出,由于使用了自定义的MyPartitioner,所有key小于20051210的的<K,V>都会放到第一个reduce中处理,key大于20051210就会被放到第二个reduce中处理。
每个reduce的输出key又是经过key排序的,所以最终的结果集降序排列。
但是如果使用上面自定义的partition类,又conf.setNumReduceTasks(1)的话,会怎样? 看下Job Counters:
- Job Counters
- Data-local map tasks=2
- Total time spent by all maps waiting after reserving slots (ms)=0
- Total time spent by all reduces waiting after reserving slots (ms)=0
- SLOTS_MILLIS_MAPS=16395
- SLOTS_MILLIS_REDUCES=3512
- Launched map tasks=2
- Launched reduce tasks=1
只启动了一个reduce。
(1)、 当setNumReduceTasks( int a) a=1(即默认值),不管Partitioner返回不同值的个数b为多少,只启动1个reduce,这种情况下自定义的Partitioner类没有起到任何作用。
(2)、 若a!=1:
a、当setNumReduceTasks( int a)里 a设置小于Partitioner返回不同值的个数b的话:
- public int getPartition(IntWritable key, IntWritable value, int numPartitions) {
- /* Pretty ugly hard coded partitioning function. Don't do that in practice, it is just for the sake of understanding. */
- int nbOccurences = key.get();
- if (nbOccurences < 20051210)
- return 0;
- if (nbOccurences >= 20051210 && nbOccurences < 20061210)
- return 1;
- if (nbOccurences >= 20061210 && nbOccurences < 20081210)
- return 2;
- else
- return 3;
- }
同时设置setNumReduceTasks( 2)。
于是抛出异常:
- 11/03/25 17:03:41 INFO mapreduce.Job: Task Id : attempt_201103241018_0023_m_000000_1, Status : FAILED
- ava.io.IOException: Illegal partition for 20110116 (3)
- at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:900)
- at org.apache.hadoop.mapred.MapTask$OldOutputCollector.collect(MapTask.java:508)
- at com.alipay.dw.test.KpiMapper.map(Unknown Source)
- at com.alipay.dw.test.KpiMapper.map(Unknown Source)
- at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:54)
- at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:397)
- at org.apache.hadoop.mapred.MapTask.run(MapTask.java:330)
- at org.apache.hadoop.mapred.Child$4.run(Child.java:217)
- at java.security.AccessController.doPrivileged(Native Method)
- at javax.security.auth.Subject.doAs(Subject.java:396)
- at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:742)
- at org.apache.hadoop.mapred.Child.main(Child.java:211)
某些key没有找到所对应的reduce去处。原因是只启动了a个reduce。
b、当setNumReduceTasks( int a)里 a设置大于Partitioner返回不同值的个数b的话,同样会启动a个reduce,但是只有b个redurce上会得到数据。启动的其他的a-b个reduce浪费了。
c、理想状况是a=b,这样可以合理利用资源,负载更均衡。
reduce的数目到底和哪些因素有关的更多相关文章
- 019_Map Task数目的确定和Reduce Task数目的指定
注意标题:Map Task数目的确定和Reduce Task数目的指定————自然得到结论,前者是后者决定的,后者是人为指定的.查看源码可以很容易看懂 1.MapReduce作业中Map Task数目 ...
- reduce个数问题
reduce的数目到底和哪些因素有关 1.我们知道map的数量和文件数.文件大小.块大小.以及split大小有关,而reduce的数量跟哪些因素有关呢? 设置mapred.tasktracker.r ...
- reduce个数究竟和哪些因素有关
reduce的数目究竟和哪些因素有关 1.我们知道map的数量和文件数.文件大小.块大小.以及split大小有关,而reduce的数量跟哪些因素有关呢? 设置mapred.tasktracker.r ...
- MapReduce剖析笔记之五:Map与Reduce任务分配过程
在上一节分析了TaskTracker和JobTracker之间通过周期的心跳消息获取任务分配结果的过程.中间留了一个问题,就是任务到底是怎么分配的.任务的分配自然是由JobTracker做出来的,具体 ...
- Hadoop Map/Reduce教程
原文地址:http://hadoop.apache.org/docs/r1.0.4/cn/mapred_tutorial.html 目的 先决条件 概述 输入与输出 例子:WordCount v1.0 ...
- 一步一步跟我学习hadoop(5)----hadoop Map/Reduce教程(2)
Map/Reduce用户界面 本节为用户採用框架要面对的各个环节提供了具体的描写叙述,旨在与帮助用户对实现.配置和调优进行具体的设置.然而,开发时候还是要相应着API进行相关操作. 首先我们须要了解M ...
- MapReduce流程、如何统计任务数目以及Partitioner
核心功能描述 应用程序通常会通过提供map和reduce来实现 Mapper和Reducer接口,它们组成作业的核心. Map是一类将输入记录集转换为中间格式记录集的独立任务. 这种转换的中间格式记录 ...
- 分布式基础学习(2)分布式计算系统(Map/Reduce)
二. 分布式计算(Map/Reduce) 分 布式式计算,同样是一个宽泛的概念,在这里,它狭义的指代,按Google Map/Reduce框架所设计的分布式框架.在Hadoop中,分布式文件 系统,很 ...
- hadoop学习WordCount+Block+Split+Shuffle+Map+Reduce技术详解
转自:http://blog.csdn.net/yczws1/article/details/21899007 纯干货:通过WourdCount程序示例:详细讲解MapReduce之Block+Spl ...
随机推荐
- Measuring the amount of writes in InnoDB redo logs
Choosing a good InnoDB log file size is key to InnoDB write performance. This can be done by measuri ...
- mysql中的semi-join
1. 背景介绍 什么是semi-join? 所谓的semi-join是指semi-join子查询. 当一张表在另一张表找到匹配的记录之后,半连接(semi-jion)返回第一张表中的记录.与条件连接相 ...
- 检测php网站是否已经被攻破
from :http://www.gregfreeman.org/2013/how-to-tell-if-your-php-site-has-been-compromised/ http://drop ...
- 设置EDIUS字幕时有哪些要注意的
我们在用EDIUS添加字幕,有时候可能会遇到以下麻烦.例如有的字体在EDIUS中找不到,诗歌的排版问题还有怎么给字幕加光效等等.今天小编主要来给大家解决这三个问题,让你们知道EDIUS字幕设置时应该注 ...
- TaffyDB:开源JavaScript数据库
你是否曾经注意到javascript的对象有点像数据库中的记录,你把很多javascript对象包装到一起时就像是你在处理一个数据库中的表,TaffyDB是一个Javascript库,它提供了强大的数 ...
- 【转】Android Drawable Resource学习(十一)、RotateDrawable
对另一个drawable资源,基于当前的level,进行旋转的drawable. 文件位置: res/drawable/filename.xml文件名即资源名 编译数据类型: 指向 RotateDra ...
- 转载:使用sklearn做单机特征工程
目录 1 特征工程是什么?2 数据预处理 2.1 无量纲化 2.1.1 标准化 2.1.2 区间缩放法 2.1.3 标准化与归一化的区别 2.2 对定量特征二值化 2.3 对定性特征哑编码 2.4 缺 ...
- Worktile 团队协同办公工具
Worktile是一个团队协同办公工具,通过简单的协作.沟通和分享,实现团队交互与任务管理的轻松协作.工作随身带,多平台.云数据,随时随地与团队一起工作,项目.任务.文件.讨论.文档.事件.活动流.通 ...
- 在eclipse中的tomcat内存设置
设置步骤如下: 1.点击eclipse上的debug图标旁边的下拉箭头 2.然后选择Run Configurations, 3.系统弹出设置tomcat配置页面,在Argument中末尾添加参数中的V ...
- Oracle监控代理安装ITM(IBM Tivoli Monitoring)
1 监控代理安装 2 1.1 安装 2 1.1.1 解压安装包 2 1.1.2 安装 2 1.2 配置 5 1.2.1 给Agent授权 5 1.2.2 配置Oracle Agent 10 目录 1 ...