学习笔记:MapReduce的类型

版权声明:原创文章,谢绝转载 https://blog.csdn.net/m0_37367424/article/details/84295582

学习笔记:MapReduce的类型

  • 总结自8.1节:MapReduce的类型 P207-218

MapReduce中map与reduce函数遵循格式如下:

	map:(k1, v1) -> list(k2, v2)
	reduce:(k2, list(v2))-> list(k3, v3)

一般来说map函数输入的键/值(K1/V1)类型不同于输出类型(K2/V2),但map函数的输出类型需要与reduce的输入类型相同。但reduce的输出类型可以不同于reduce的输入类型。

如果使用combiner函数的话,格式会变为以下:

	map:(k1, v1) -> list(k2, v2)
	combiner:(k2, list(v2)) ->  list(k2, v2)
	reduce:(k2, list(v2))-> list(k3, v3)

由上可知,通常combiner函数与reduce函数是相同的,这种情况下,k2类型与k3相同,v2类型与v3相同。区别在于运行的阶段。

分区索引由Partitioner接口的getPartition获取。默认情况下,hadoop使用的是其默认实现:Hash分区方式,我们也可通过自己实现该接口然后通过job(job.setPartitionerClass)显式设置。

  partition:(k2, v2)-> Integer

TextInputFormat的默认键值为LongWriteable/Text。

为什么我们在Mapper和Reducer中已经声明了相关key和value的类型,我们还需要使用job.setXXX()方法呢?
答:因为java中的类型擦除:一句话总结就是泛型的类型在进入jvm后被消除,泛型仅仅用于编译器代码检查。详见:https://www.cnblogs.com/drizzlewithwind/p/6101081.html

附表:新API中的相关键值设置函数

属性 属性设置方法 输入类型 中间类型 输出类型
可以设置类型的属性
mapreduce.job.inputformat.class setInsetInputFormatClass *  *
mapreduce.map.output.key.class setMapOutputKeyClass *
mapreduce.map.output.value.class setMapOutputValueClass *
mapreduce.job.output.key.class setOutputKeyClass *
mapreduce.job.output.value.class setOutputValueClass *
类型必须一致的属性
mapreduce.job.map.class setMapperClass * * * *
mapreduce.job.combin.class setCombinerClass * *
mapreduce.job.partitioner.class setPartitionerClass * *
mapreduce.job.output.key.comparator.class setSortComparatorClass
mapreduce.job.output.group.comarator.class setGroupingComparatorClass *
mapreduce.job.reduce.class setReducerClass * * * *
mapreduce.job.outputformat.class setOutputFormatClass * *
注意事项:
1. job.setPartitionerClass(PartitionClass.class):对key取hash值(或其它处理),进入不同的reduce task
2. job.setSortComparatorClass(SortComparator.class):对进入同一个reduce task的键或键的部分进行排序;
3. job.setGroupingComparatorClass(RawComparator.class):定义一个分组规则。因为进入同一个reduce任务的数据不代表位于同一行

1. 默认的mapreduce作业

1.1 默认的map、reduce键值

在新版本API中,mapreduce的Mapper和Reducer实现由原来的实现接口改为了继承类。因此,在新API中,我们可以不用指定Mapper和Reducer实现,此时使用的是默认实现。
在默认实现中,输入类型为TextInputFormat,对应的键类型为LongWritable,表示本行数据开头在文件中的偏移量;对应的值类型为Text,表示本行数据内容。输出类型为TextOutputFormat,他将键和值转化成字符串并用字符串分隔,然后一条一条输出。

1.2 默认的分区函数。

默认的分区函数的实现是HashPartitioner,根据相关源码可知,默认的分区方式返回结果与reduce任务个数(等同于分区个数,一个分区对应一个reduce 任务)。又由于默认的reduce个数为1,即以下函数永远返回0。默认分区实现如下

     public int getPartition(K2 key, V2 value, int numReduceTasks) {
        return (key.hashCode() & 2147483647) % numReduceTasks;
    }

1.3 怎么算一个良好的reduce任务数

一条经验法则:目标reduce保持每个运行5分钟左右,且至少产生一个HDFS块输出比较合适。

2. 默认的streaming作业

2.1 默认streaming的键值

对于默认的文本模式(-o text)模式,streaming仅会传递值给mapper而忽略键,对于其他模式,设置stream.map.input.ignorekey设为true可达到相同效果。

2.2 可配置的streaming键值

streaming的分隔符属性表详细见:https://www.cnblogs.com/shay-zhangjin/p/7714868.html

猜你喜欢

转载自blog.csdn.net/m0_37367424/article/details/84295582