Hadoop中常用类型及如何自定义序列化类型

Hadoop 潘老师 3周前 (11-09) 24 ℃ (0) 扫码查看

我们在写MapReduce代码时,经常会用到一些类和数据类型,有些时候为了满足我们的业务需求,还需要自定义序列化的数据类型,下面我们一起来了解下,一些常用类和数据类型,以及我们应该如何去自定义序列化类型。

1、InputFormat类:该类的作用是将输入的文件和数据分割成许多小的split文件,并将split的每个行通过LineRecorderReader解析成,通过job.setInputFromatClass()函数来设置,默认的情况为类TextInputFormat,其中Key默认为字符偏移量,value是该行的值。

2、Mapper类:根据输入的对生成中间结果,默认的情况下使用Mapper类,该类将输入的对原封不动的作为中间按结果输出,通过job.setMapperClass()实现。实现Map函数。

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类型的对应关系:
Hadoop中常用类型及如何自定义序列化类型

我们在自定义序列化数据类型时,经常会根据该类型的使用场景,有两种方式可供选择实现:
1、如果该类型对象放在value中传输使用,则实现Writable接口。其实现格式如下:

public class  MyBean  implements  WritableComparable<MyBean  > { 实现抽象方法}

2、如果该类型对象放在key中传输使用,则实现WritableComparable接口。因为MapReduce框架中的shuffle过程一定会对key进行排序。其实现格式如下:

public class  MyBean  implements  WritableComparable<MyBean  > { 实现抽象方法}

比如我们后面的温度排序案例中,就自定义了MyKey序列化类型,具体案例,请参考:

Hadoop经典综合性案例—温度排序示例

温度排序示例是一个综合性比较强的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;
    }
}

版权声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系潘老师进行处理。
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)

您必须 微信登录 才能发表评论!

登录