3.18.1 概念

  • 序列化:将结构化对象转化为字节流以便在网络上传输或写入磁盘持久存储的过程

  • 反序列化:将字节流转回结构化对象的逆过程

  • Java 的序列化 (Serializable) 是一个重量级序列化框架, 一个对象被序列化后, 会附带很多额外的信息 (各种校验信息, header, 继承体系等), 不便于在网络中高效传输. 因此 Hadoop 自己开发了一套序列化机制(Writable), 精简高效. 不用像 Java 对象类一样传输多层的父子关系, 需要哪个属性就传输哪个属性值, 大大的减少网络传输的开销

3.18.2 应用领域

  • 进程间通信

  • 永久存储

3.18.3 特点

  • 紧凑:充分利用网络带宽资源和存储空间

  • 快速:减少序列化和反序列化的性能开销

  • 可扩展:兼容老格式的消息

  • 互操作:支持不同的语言

3.18.4 实现

  • Java 自己的序列化机制:java.io.Serializable

  • Hadoop自己的序列化机制:org.apache.hadoop.io.Writable

3.18.5 常用接口

  • org.apache.hadoop.io. Writable

    序列化的对象需实现的一个接口

    Hadoop 的 MapReduce 框架中 key 或 value 均需实现这个接口

    该接口包含两个抽象方法:


  • org.apache.hadoop.io. WritableComparable

    继承自上述 Writable 接口和 java.lang.Comparable 接口

    Hadoop 的 MapReduce 框架中的 key 必须实现这个接口

  • org.apache.hadoop.io. RawComparator

    继承自 java.util.Comparator

    一个抽象方法:可在数据流中比较对象


3.18.6 层次结构


3.18.7 Java 类型

Writable 类对 Java 基本数据类型提供了封装

  • short 和 char除外,可以使用 IntWritable 存储

  • 所有的封装包含 get() 和 set() 两方法用于读取或设置封装的值

Java基本类型Writable实现序列化大小(字节)
booleanBooleanWritable1
byteByteWritable1
shortShortWritable2
intIntWritable4
VintWritable1~5
floatFloatWritable4
longLongWritable8
VlongWritable1~9
doubleDoubleWritable8

3.18.8 Writable 定制package com.briup.Bean;


import org.apache.hadoop.io.LongWritable;

import org.apache.hadoop.io.Text;

import org.apache.hadoop.io.Writable;


import java.io.DataInput;

import java.io.DataOutput;

import java.io.IOException;


public class YearAndStation implements Writable {

    private long year;

    private String station;


    public YearAndStation() {

    }


    public YearAndStation(long year, String station) {

        this.year = year;

        this.station = station;

    }


    public long getYear() {

        return year;

    }


    public void setYear(long year) {

        this.year = year;

    }


    public String getStation() {

        return station;

    }


    public void setStation(String station) {

        this.station = station;

    }


    @Override

    public String toString() {

        return "YearAndStation{" +

                "year=" + year +

                ", station=" + station +

                '}';

    }


    /**

     *序列化

     */

    public void write(DataOutput out) throws IOException {

        out.writeLong(year);

        out.writeUTF(station);

    }


    /**

     * 反序列化

     */

    public void readFields(DataInput in) throws IOException {

        this.year=in.readLong();

        this.station=in.readUTF();

    }

}

注意:

序列化对象作为Mapper输出的键基于WritableComparable定制,换言之,定制的序列化对象需要比较规则或排序规则基于WritableComparable实现,否则可以使用Writable实现

序列化和反序列化中写和读取数据的顺序必须保持一致




最后修改: 2023年12月28日 星期四 15:00