MapReduce的类型与格式

  • MapReduce的类型

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

如果使用combiner函数,它与reduce函数形式相同,不同之处是它的输入类型是中间的键-值对类型(K2,V2),这些中间值可以输入reduce函数如下图:MapReduce的类型与格式_第1张图片

combiner函数与reduce函数通常是一样的,在这种情况下,K3与K2类型相同,V3与V2类型相同。

patition函数对中间结果的键-值对(K2和V2)进行处理,并且返回一个分区索引。实际上,分区由键单独决定(值被忽略) 

 分区数等于作业的reduce任务个数。键的哈希码被转换成一个非负整数,它由哈希值和最大的整型值做一次按位与操作,然后用分区数进行取模操作,来决定该记录属于哪个分区索引。

默认情况下,只有一个reducer,也就是只有一个分区,但在实际的应用中,通常会把reducer数设置为较大的数,否则由于所有的中间数据都会放到一个reduce任务中,作业处理极其低效。目标reducer保持在每个运行5分钟左右,且产生至少一个HDFS块的输出比较合适。

  • 输入格式

一个输入分片就是一个由单个map操作来处理的输入块,每一个map操作只处理一个输入分片。每个分片被划分为若干个记录,每条记录就是一个键值对,map一个接一个的处理记录。在数据库的场景下,一个输入分片可以对应于一个表上的若干行,而每一条记录对应到一行。(DBInputFormat的输入格式用于从关系数据库中读取数据)

输入分片在Java中表示为InputSplit接口,包含一个以字节为单位的长度和一组存储位置(即一组主机名),分片并不包含数据本身,而是指向数据的引用,存储位置供MapReduce系统使用以便将map任务尽量放在分片数据附近,而分片大小用来排序分片,以便优先处理最大的分片,从而最小化作业运行时间。InputFomat创建InputSplit,负责创建输入分片并将它们分割成记录。RecordReader像是记录上的迭代器,map任务用一个RecordReader来生成记录的键-值对,然后再传递给map函数。在使用不管是mapper和reducer接口中,迭代器会被反复使用,所以在调用迭代器之间,一定要复制任何需要保留的任何对象。

MapReduce的类型与格式_第2张图片

MapReduce处理数据的最佳速度最好与数据在集群中的传输速度相同,而处理小文件将增加运行作业而必需的寻址次数。在HDFS中集群中存储大量的小文件会浪费namenode的内存。一个可以减小大量小文件的方法是使用顺序文件将这些小文件合并成一个或多个大文件,可以将文件名作为键,文件名作为值,如果HDFS中已经有大量的小文件,CombineFileInputFormat方法比较适合(将多个小文件打包到一个分片中以便每个mapper可以处理更多的数据)

你可能感兴趣的:(Hadoop,MapReduce,Hadoop,大数据)