Hadoop 数据类型及序列化

1.Hadoop数据类型

Java类型 Hadoop Writable类型
Boolean BooleanWritable
Byte ByteWritable
Int IntWritable
Float FloatWritable
Long LongWritable
Double DoubleWritable
String Text
Map MapWritable
Array ArrayWritable
Null NullWritable

2.为何Hadoop有自身序列化与反序列化

  • Java自身的序列化除去本身Bean的数据外,携带了各种校验信息、头及继承体系等,本身比较重,Hadoop自身的序列化则仅携带了轻量的简单校验信息,因此可以达到集群之间存储空间少、传输速度快的特性。
  • 自身实现的序列化可以实现在不同的开发语言下互相之间序列/反序列,更好的互操作性。

3.自定义Hadoop序列/反序列 Bean类型

  1. 必须实现Writable接口
  2. 反序列化时,需要反射调用空参构造函数,所以必须有空参构造函数
    public FlowBean(){
        super();
    }
  1. 重写序列化方法
    /**
     * 序列化方法
     * @param dataOutput
     * @throws IOException
     */
    @Override
    public void write(DataOutput dataOutput) throws IOException {
        dataOutput.writeLong(upFlow);
        dataOutput.writeLong(downFlow);
        dataOutput.writeLong(sumFlow);
    }
  1. 重写反序列化方法
    /**
     * 反序列化方法
     * 注意,反序列化时数据的顺序必须和序列化时的顺序完全一致
     * @param dataInput
     * @throws IOException
     */
    @Override
    public void readFields(DataInput dataInput) throws IOException {
        upFlow = dataInput.readLong();
        downFlow = dataInput.readLong();
        sumFlow = dataInput.readLong();
    }
  1. 要想把结果显示在文件中,需要重写toString(),可用\t分开,方便后续使用。
    @Override
    public String toString() {
        return "FlowBean{}";
    }
  1. 如果需要将自定义的Bean放在key中传输,则还需要实现Comparable接口,因为MapReduce框架中的Shuffle过程要求对key必须能排序。
    @Override
    public int compareTo(FlowBean o) {
        return this.sumFlow > o.getSumFlow() ? -1 : 1;
    }

完整代码如下

package cn.coreqi.mapreduce.writable;

import org.apache.hadoop.io.Writable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

/**
 * 1.定义类实现 Writable 接口
 * 2.重写空参构造函数
 * 3.重写序列化和反序列化方法
 * 4.toString()方法
 * 5.如果自定义的Bean需要放在key中传输,则还需要实现Comparable接口
 */
public class FlowBean implements Writable,Comparable<FlowBean>{

    private long upFlow;    //上行流量

    private long downFlow;  //下行流量

    private long sumFlow;   //总流量

    public long getUpFlow() {
        return upFlow;
    }

    public void setUpFlow(long upFlow) {
        this.upFlow = upFlow;
    }

    public long getDownFlow() {
        return downFlow;
    }

    public void setDownFlow(long downFlow) {
        this.downFlow = downFlow;
    }

    public long getSumFlow() {
        return sumFlow;
    }

    public void setSumFlow(long sumFlow) {
        this.sumFlow = sumFlow;
    }

    public void setSumFlow() {
        this.sumFlow = this.upFlow + this.downFlow;
    }

    /**
     * 空参构造函数
     */
    public FlowBean(){
        super();
    }

    /**
     * 序列化方法
     * @param dataOutput
     * @throws IOException
     */
    @Override
    public void write(DataOutput dataOutput) throws IOException {
        dataOutput.writeLong(upFlow);
        dataOutput.writeLong(downFlow);
        dataOutput.writeLong(sumFlow);
    }

    /**
     * 反序列化方法
     * 注意,反序列化时数据的顺序必须和序列化时的顺序完全一致
     * @param dataInput
     * @throws IOException
     */
    @Override
    public void readFields(DataInput dataInput) throws IOException {
        upFlow = dataInput.readLong();
        downFlow = dataInput.readLong();
        sumFlow = dataInput.readLong();
    }

    @Override
    public String toString() {
        return upFlow + "\t" + downFlow + "\t" + sumFlow;
    }

    @Override
    public int compareTo(FlowBean o) {
        return this.sumFlow > o.getSumFlow() ? -1 : 1;
    }
}
posted @ 2023-12-13 19:04  SpringCore  阅读(15)  评论(0编辑  收藏  举报