我们在写MapReduce代码时,经常会用到一些类和数据类型,有些时候为了满足我们的业务需求,还需要自定义序列化的数据类型,下面我们一起来了解下,一些常用类和数据类型,以及我们应该如何去自定义序列化类型。
1、InputFormat类:该类的作用是将输入的文件和数据分割成许多小的split文件,并将split的每个行通过LineRecorderReader解析成
2、Mapper类:根据输入的
3、Combine类:实现combine函数,该类的主要功能是合并相同的key键,通过job.setCombinerClass()方法设置,默认为null,不合并中间结果。实现map函数
4、Partitioner类: 该该主要在Shuffle过程中按照Key值将中间结果分成R份,其中每份都有一个Reduce去负责,可以通过job.setPartitionerClass()方法进行设置,默认的使用hashPartitioner类。实现getPartition函数
5、Reducer类:将中间结果合并,得到中间结果。通过job.setReduceCalss()方法进行设置,默认使用Reducer类,实现reduce方法。
6、OutPutFormat类:该类负责输出结果的格式。可以通过job.setOutputFormatClass()方法进行设置。默认使用TextOUtputFormat类,得到
下面这张图中写明了Hadoop中已经存在的常用序列化数据类型和Java类型的对应关系:
我们在自定义序列化数据类型时,经常会根据该类型的使用场景,有两种方式可供选择实现:
1、如果该类型对象放在value
中传输使用,则实现Writable
接口。其实现格式如下:
public class MyBean implements WritableComparable<MyBean > { 实现抽象方法}
2、如果该类型对象放在key
中传输使用,则实现WritableComparable
接口。因为MapReduce框架中的shuffle过程一定会对key进行排序。其实现格式如下:
public class MyBean implements WritableComparable<MyBean > { 实现抽象方法}
比如我们后面的温度排序案例中,就自定义了MyKey
序列化类型,具体案例,请参考:
温度排序示例是一个综合性比较强的Hadoop经典案例,除了基础的MapReduce,还有自定义序列化对象、分区 […]
其部分代码如下,可供参考:
/** * 自定义时间温度的封装类 */ public class MyKey implements WritableComparable<MyKey> { private int year;//年 private int month;//月 private int temp;//温度 public int getYear() { return year; } public void setYear(int year) { this.year = year; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public int getTemp() { return temp; } public void setTemp(int temp) { this.temp = temp; } //序列化:通过write方法写入序列化数据流 @Override public void write(DataOutput out) throws IOException { out.writeInt(year); out.writeInt(month); out.writeInt(temp); } //反序列化:通过readFields方法从序列化的数据流中读出进行赋值 @Override public void readFields(DataInput in) throws IOException { //注意读取顺序要和序列化顺序保持一致 year = in.readInt(); month = in.readInt(); temp = in.readInt(); } //按照字典顺序进行比较,返回值是一个int型 public int compareTo(MyKey mykey) { return this==mykey?0:-1; } }