hadoop学习笔记4
Writable接口
1、对java中的int型进行封装那么就是hadoop中的IntWritable类,在写程序的时候可以把IntWritable可以看着是int类型,它实现了WritableComparable接口,WritableComparable又是Writable、java.lang.comparable接口的子接口。
2、我们可以自定义Writable接口,来编写更复杂的结构的类,核心:hadoop有自己一套的I/O机制,I/O类都必须实现Writable接口。
------------------------
mapreduce驱动默认的设置
inputFormat(输入)-----TextInputFormat
MapperClass ------------IdentityMapper
MapRunnerClass(map启动类)---------MapRunner
MapOuputKeyClass-------------LongWritable
MapOutputValueClass--------Text
PartitionerClasss----------HashPartitioner
ReduceClass ---------------IdentityReduce
OutputKeyClass --------------LongWritable
OutputValueClass--------------Text
OutputFormatClass----------TextOutputFormat
---------------------------------------------------
Combiners和Partitioner编程
Combiners的作用
?每一个map可能会产生大量的输出,combiner的作用就是在map端对输出先做一次合并,以减少传输到reducer的数据量,
?? 1)combiner最基本是实现本地key的聚合,对map输出的key排序,value进行迭代。如下所示:map: (K1, V1) → list(K2, V2)?combine: (K2, list(V2)) → list(K2, V2)?reduce: (K2, list(V2)) → list(K3, V3)
?? 2)combiner还具有类似本地的reduce功能.例如hadoop自带的wordcount的例子和找出value的最大值的程序,combiner和reduce完全一致。如下所示:map: (K1, V1) → list(K2, V2)?combine: (K2, list(V2)) → list(K3, V3)?reduce: (K3, list(V3)) → list(K4, V4)?
? 3)如果不用combiner,那么,所有的结果都是reduce完成,效率会相对低下。使用combiner,先完成的map会在本地聚合,提升速度。
?? 4)对于hadoop自带的wordcount的例子,value就是一个叠加的数字,所以map一结束就可以进行reduce的value叠加,而不必要等到所有的map结束再去进行reduce的value叠加。
注意:combiner使用的合适,可以在满足业务的情况下提升job的速度,如果不合适,则将导致输出的结果不正确。
Combiner的输出是Reducer的输入,Combiner绝不能改变最终的计算结果。所以从我的想法来看,Combiner只应该用于那种Reduce的输入key/value与输出key/value类型完全一致,且不影响最终结果的场景。比如累加,最大值等。
-------------------------------------------------
?Combiners分析
假设有两个map。
第一个map的输出为:
(1950,0)
?(1950,20)
?(1950,10)
第二个map输出为:
(1950,25)
?(1950,15)
?(1950,30)
Reduce函数被调用是,输入如下:
(1950,[0,20,10,25,15,30])
因为30是最大的值,所以输出如下:
(1950,30)
如果我们使用 combiner:那么reduce调用的时候传入的数据如下:
(1950,[20,30])--?(1950,30)
用表达式表示为:
Max(0,20,10,25,15,30)=max(max(0,20,10),max(25,15,30))=max(20,30)=30
----------------------------------------
使用 Combiners要小心
刚才我们是计算最大值可以使用Combiners能提高效率。
如果我们要是求平均值呢?
Avg(0,20,10,25,15,30) = 15
如果使用Combiner会得到什么样的结果呢?
第一个map输出为:
?avg(0,20,10) = 10
第二个map输出为:
Avg(25,15,30) = 23
输入到reduce出来的结果为:
Avg(10,23) = 17.5
17.5和15?
所以 :使用combiner一定要注意。