关于map:
map的个数取决于文件的切割之后的份数,hdfs中的block默认是64m
切割只能对二进制文件和非文件可行,压缩文件不可行
切割block的size计算:
splitSize= max[minSize, min(goalSize, blockSize)]
minSize= ${mapred.min.split.size} (这个就是可以设置block的size)
goalSize= totalSize/${mapred.map.tasks}(这个是计算的size,总文件大小和设定的map 数)
关于reduce:
reduce的个数设定和两个有关,主要是setNumReduceTasks()和getPartition有关, setNumReduceTasks很好理解,就是设置reduce个数,但是有时候会发现reduce的个数和设置的不对,这是为什么?map输出之后怎么把对应的文件分配到对应的reduce呢,主要是通过partioner方法,reduce默认的是hashPartioner,我们看下他的方法
numReduceTasks的值就是setNumReduceTasks的值。不该写这个方法的话,那和setNumReduceTasks值是一样的,有时候有些比如说我就要0号reduce处理的话,那改写这个方法就可以了,设置setNumReduceTasks也没用。
关于文件的切割和读取:
hadoop的文件切割主要是inputformat接口来实现的,这个接口有两个方法getSplit和getRecordReader,前者主要是用来切割文件用的,后者是用来读取数据的。切割的数据元是存储在InputSplit接口的实现类中,里面定义了这个块的长度,位置信息等等!RecordReader里面定义了如何读取每一条记录,LineReader内部类中的readLine方法就是,里面包括如何处理缺省记录的处理代码!分析见blog[url]http://hi.baidu.com/lzpsky/blog/item/99d58738b08a68e7b311c70d.html[/url]
关于Combiner:
map的把数据读入内存然后进行处理之后的数据,会放到内存buffer中,这个buff的值是可以设置的,当阀值到80%的时候,buff会把数据spill一个文件到磁盘中,然后这些split文件会merge生成一个块文件(spilt之后的文件通过索引来聚合)。然后使用Combiner可以使得map端聚合(举例:输出的记录都是key,value键值对,相同的key其实可以合并成为一个key,减少磁盘和网络,combiner就是做这个事情的)。它继承reduce接口
[img]http://dl.iteye.com/upload/attachment/0070/1096/c328b4d2-e6c5-3ff4-8ecd-d37dc8769f3e.png[/img]
关于通过实现Comparator接口来进行二次排序:
map的个数取决于文件的切割之后的份数,hdfs中的block默认是64m
切割只能对二进制文件和非文件可行,压缩文件不可行
切割block的size计算:
splitSize= max[minSize, min(goalSize, blockSize)]
minSize= ${mapred.min.split.size} (这个就是可以设置block的size)
goalSize= totalSize/${mapred.map.tasks}(这个是计算的size,总文件大小和设定的map 数)
关于reduce:
reduce的个数设定和两个有关,主要是setNumReduceTasks()和getPartition有关, setNumReduceTasks很好理解,就是设置reduce个数,但是有时候会发现reduce的个数和设置的不对,这是为什么?map输出之后怎么把对应的文件分配到对应的reduce呢,主要是通过partioner方法,reduce默认的是hashPartioner,我们看下他的方法
/** Use {@link Object#hashCode()} to partition. */
public int getPartition(K2 key, V2 value,
int numReduceTasks) {
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
numReduceTasks的值就是setNumReduceTasks的值。不该写这个方法的话,那和setNumReduceTasks值是一样的,有时候有些比如说我就要0号reduce处理的话,那改写这个方法就可以了,设置setNumReduceTasks也没用。
关于文件的切割和读取:
hadoop的文件切割主要是inputformat接口来实现的,这个接口有两个方法getSplit和getRecordReader,前者主要是用来切割文件用的,后者是用来读取数据的。切割的数据元是存储在InputSplit接口的实现类中,里面定义了这个块的长度,位置信息等等!RecordReader里面定义了如何读取每一条记录,LineReader内部类中的readLine方法就是,里面包括如何处理缺省记录的处理代码!分析见blog[url]http://hi.baidu.com/lzpsky/blog/item/99d58738b08a68e7b311c70d.html[/url]
关于Combiner:
map的把数据读入内存然后进行处理之后的数据,会放到内存buffer中,这个buff的值是可以设置的,当阀值到80%的时候,buff会把数据spill一个文件到磁盘中,然后这些split文件会merge生成一个块文件(spilt之后的文件通过索引来聚合)。然后使用Combiner可以使得map端聚合(举例:输出的记录都是key,value键值对,相同的key其实可以合并成为一个key,减少磁盘和网络,combiner就是做这个事情的)。它继承reduce接口
[img]http://dl.iteye.com/upload/attachment/0070/1096/c328b4d2-e6c5-3ff4-8ecd-d37dc8769f3e.png[/img]
关于通过实现Comparator接口来进行二次排序: