Hadoop The Definitive Guide 2nd读书笔记 – 第七章

本章主要介绍了Hadoop中的各种数据类型……

1、从泛型的角度看问题。
箭头代表从输入到输出
map(k1, v1) -> list(k2, v2)
combine(k2, list(v2)) -> list(k2, v2)
reduce(k2, list(v2)) -> list(k3, v3)

2、从1中可以看到,map的输出k2 v2和reduce的输入k2和v2必须相同。
如果有combine的话,map的输出也必须和combine相匹配。

3、map输入的初始k1和v1由InputFormat决定,默认是TextInputFormat,即key为LongWritable且value为Text。

4、默认的k和v都是按照map的input来决定的,如果不匹配,比如k2和k1不是一个类型,则需要调用setMapOutputKeyClass()。而setOutputKeyClass()同时设定了k2和k3即OutPut = map output + reduce ouput。

个人感觉这一涉及挺扯淡的,泛型是做什么用的,自己不能推断出来么,还要我自己设……书上的解释我也没太看懂。。

关于这些泛型需要设置的函数类型,小结一下吧:
(按照1中的kx和vx来)

K1/V1:SetInputFormat()(同时包含了Key和Value的类型)
K2:SetMapOutputKeyClass()
V2:SetMapOutputValueClass()
K2 + K3:SetOutputKeyClass() 注意是同时对map和reduce的输出设置哦!
V2 + V3:SetOutputValueClass() 同上!

5、一定要记得设置Map/Reduce类,通过如下的方法。
setMapperClass()
setReducerClass()
setCombinerClass()
不设置也不会报错的,但只是将input转为output,没有任何意义。

6、reduce都需要划分,来决定哪个key归哪个task,这是由Partitioner决定的,可以通过Job的setPartitionerClass()来设置,一般用默认的Hash即可。

7、reduce个数的设置:理想情况是略少于集群reduce的槽的个数,即争取一波搞定!

8、默认的输出是TextOutputFormat,他会将Collector的key和value转化为一行一行输出。

9、当使用Streaming时(即非Java的Map),注意只传入value,不传入key?由于短期内没有Streaming的需求,所以跳过先。

10、Input对应的数据类型是InputSplit,一般无需直接操作,由InputFormat代劳去读取每个InputSplit,转成对应记录。

11、每次进入map函数时,key和value都是会重用回收的,而不是如我们所想的是不变的。比如Text的Value如果你又引用了一份,那么下次调用时它的实际值已经是变了的。如果你需要记录下,自己new一个吧。。

12、FileInputFormat是InputFormat接口的默认实现,主要提供了生成InputSplit的实现。\
List getSplits(JobContext job)

13、FileInputFormat的另外重要方法是addInputPath()和setOutputPath()。input可以是文件夹、文件等等。

14、如果在input目录要排除,可以额外设置黑名单,setInputPathFilter()。不管你设置不设置filter,默认都是不遍历以点.和下划线_开头的文件的。

15、FileInputFromat只切分大于HDFS的Block(dfs.block.size)的文件。

16、Split的默认大小是max(minimumSize, min(maximumSize, blockSize))
而一般minimumSize < blockSize < maximumSize,所以默认是64MB(Block大小)

17、一般来说,直接改变dfs.block.size到128 MB就可以了。

18、再重复一下。。Hadoop works better with a small number of large files than a large number of small files.所以,建议采用CombineFileInputFormat把小文件打包或者SequenceFile,直接转化为好用的Key/value格式。

19、CombineFileInputFormat需要你自己实现一些东西。

20、让input不分spill的方法
(1)设置the minimum split size到Long.MAX_VALUE
(2)继承FileInputFormat,让isSplitable()返回false

21、需要直接处理key和整篇content的情况

public class WholeFileInputFormat
extends FileInputFormat<NullWritable, BytesWritable> {
@Override
protected boolean isSplitable(FileSystem fs, Path filename) {
return false;
}
@Override
public RecordReader<NullWritable, BytesWritable> getRecordReader(
InputSplit split, JobConf job, Reporter reporter) throws IOException {
}

22、TextInputFormat,key是Longwritable,偏移,value是text。

23、InputSplit可能跨越不同的HDFS Block

24、KeyValueTextInputFormat:通过key.value.separator.in.input.line做为分割,把文本的每行切分成key和value对。

25、NLineInputFormat,一次塞多行给map函数

26、对于XML文件,提供了StreamXmlRecordReader。

27、SequenceFileInputFormat,很重要的角色。它也可以转化为TextInputFormat用。使用SequenceFileAsTextInputFormat类。

28、对于输入数据源异构的情况……使用MultipleInputs.addInputPath(conf, ncdcInputPath,
TextInputFormat.class, MaxTemperatureMapper.class),同时指定不同的input路径和对应的map类

29、数据库中的数据也可以用在Hadoop中,用DBInputFormat,但要map太多会让数据库挂掉……也可以用Sqoop做大量数据库->Hadoop格式的转换。

30、TextOutputFormat是默认的输出,用mapred.textoutputformat.separator设置输出分隔符。用NullWritable可禁止key或者value的输出。

31、SequenceFileOutputFormat,直接将输出为SequenceFile,对于马上要用作其他map/reduce的输入特别有用。

32、一般的输出都是part-00000 part-00001,如果你需要控制文件名,使用MultipleOutputFormat和MultipleOutputs。

33、默认即使是空文件,也会产生part-xxxxx文件,而LazyOutputFormat不会。

34、DatabaseOutput:写结果到RDBMS或者HBase。

Leave a Reply

Your email address will not be published. Required fields are marked *