文档章节

hadoop 序列化框架

政委007
 政委007
发布于 2017/05/03 09:20
字数 937
阅读 52
收藏 1

hadoop 序列化框架

[toc]

序列化,反序列化

序列化: 按照一定格式把一个对象编码成一个字节流,可以存储在硬盘,可以在网络中传递,可以拷贝,克隆 等, 反序列化: 把存入字节流的对象,解析成一个对象。

java 序列化

序列化接口: Serializable 输入输出: ObjectInputStream 和 ObjectOutputStream 的 readObject() 和writeObject() 序列化内容:对象类,类签名,非静态成员变量值,所有父类对象,其他引用的对象等

hadoop序列化

Writable接口

InterfaceAudience.Public
InterfaceStability.Stable
public interface Writable {
  /** 
   * 输出对象到数据流中
   */
  void write(DataOutput out) throws IOException;

  /** 
   * Deserialize the fields of this object from <code>in</code>.  
   * 从流中读取对象,为了效率,尽可能复用现有对象
   */
  void readFields(DataInput in) throws IOException;
}

介绍几个重要的接口:

WritableComparable : 有比较能力的序列化接口,同时继承了writable 和 comparable 接口, ByteWritable,IntWritable,DoubleWritable 等java 基本类型对应的Writable 都继承了这个接口 RawComparator : 允许从流中读取未被反序列化的对象进行比较。 WritableComparator : RawComparator 的通用实现类

例子 ObjectWirtable 类

主要成员变量

  //需要序列化,反序列化的类名
  private Class declaredClass;
  //被封装的对象的实例
  private Object instance;
  private Configuration conf;

序列化方法

      
      
    @Override
    public void write(DataOutput out) throws IOException {
        writeObject(out, instance, declaredClass, conf);
    }
    public static void writeObject(DataOutput out, Object instance,
                                 Class declaredClass, 
                                 Configuration conf) throws IOException {
        writeObject(out, instance, declaredClass, conf, false);
    }

    public static void writeObject(DataOutput out, Object instance,
        Class declaredClass, Configuration conf, boolean allowCompactArrays) 
    throws IOException {
    //判断实例是不是为null
    if (instance == null) {                       // null
      instance = new NullInstance(declaredClass, conf);
      declaredClass = Writable.class;
    }
    //判断是不是基本类型的数组
    // Special case: must come before writing out the declaredClass.
    // If this is an eligible array of primitives,
    // wrap it in an ArrayPrimitiveWritable$Internal wrapper class.
    if (allowCompactArrays && declaredClass.isArray()
        && instance.getClass().getName().equals(declaredClass.getName())
        && instance.getClass().getComponentType().isPrimitive()) {
      instance = new ArrayPrimitiveWritable.Internal(instance);
      declaredClass = ArrayPrimitiveWritable.Internal.class;
    }

    UTF8.writeString(out, declaredClass.getName()); // always write declared
    
    if (declaredClass.isArray()) {     // non-primitive or non-compact array
      int length = Array.getLength(instance);
      out.writeInt(length);
      for (int i = 0; i < length; i++) {
        writeObject(out, Array.get(instance, i),
            declaredClass.getComponentType(), conf, allowCompactArrays);
      }
      
    } else if (declaredClass == ArrayPrimitiveWritable.Internal.class) {
      ((ArrayPrimitiveWritable.Internal) instance).write(out);
      
    } else if (declaredClass == String.class) {   // String
      UTF8.writeString(out, (String)instance);
     //判断是否是基本类型
    } else if (declaredClass.isPrimitive()) {     // primitive type

      if (declaredClass == Boolean.TYPE) {        // boolean
        out.writeBoolean(((Boolean)instance).booleanValue());
      } else if (declaredClass == Character.TYPE) { // char
        out.writeChar(((Character)instance).charValue());
      } else if (declaredClass == Byte.TYPE) {    // byte
        out.writeByte(((Byte)instance).byteValue());
      } else if (declaredClass == Short.TYPE) {   // short
        out.writeShort(((Short)instance).shortValue());
      } else if (declaredClass == Integer.TYPE) { // int
        out.writeInt(((Integer)instance).intValue());
      } else if (declaredClass == Long.TYPE) {    // long
        out.writeLong(((Long)instance).longValue());
      } else if (declaredClass == Float.TYPE) {   // float
        out.writeFloat(((Float)instance).floatValue());
      } else if (declaredClass == Double.TYPE) {  // double
        out.writeDouble(((Double)instance).doubleValue());
      } else if (declaredClass == Void.TYPE) {    // void
      } else {
        throw new IllegalArgumentException("Not a primitive: "+declaredClass);
      }
    } else if (declaredClass.isEnum()) {         // enum
      UTF8.writeString(out, ((Enum)instance).name());
    } else if (Writable.class.isAssignableFrom(declaredClass)) { // 其他实现了writable接口的类型
      UTF8.writeString(out, instance.getClass().getName());
      ((Writable)instance).write(out);

    } else if (Message.class.isAssignableFrom(declaredClass)) {
      ((Message)instance).writeDelimitedTo(
          DataOutputOutputStream.constructOutputStream(out));
    } else {
      throw new IOException("Can't write: "+instance+" as "+declaredClass);
    }
  }
  

上边介绍的writable 接口的序列化,主要应用在mapreduce 过程中输入输出,但是hadoop还支持了其他序列化方法,包括hadoop Avro, Apache Thrift 和Google Protocol Bufferd等但是这些主要应用在远程rpc通信。对应数据存储例如:map的输出,reduce输出等就主要用到writable接口实现的类。

hadoop简单的序列化框架

序列化类图

接口 Serialzation

方法:

    //判断序列化实现是否支持该类对象
    boolean accept(Class<?> c);
    //获取用于序列化的对象Serializer的实现
    Serializer<T> getSerializer(Class<T> c);
    //获取用于反序列化的对象Deserializer实现
    Deserializer<T> getDeserializer(Class<T> c);

接口 Serializer

    //打开流,为序列化准备
  void open(OutputStream out) throws IOException;
    //开始将对象序列化到流中
  void serialize(T t) throws IOException;
    //关闭流,结束序列化,清理 
  void close() throws IOException;

接口 Deserializer

与序列化过程类似

java序列化支持

主要实现了Serialzation 接口,并且有两个静态内部类JavaSerializationDeserializer 和 JavaSerializationSerializer 分别实现Deserializer 和Serializer 接口 具体代码可以查看 hadoop 项目hadoop-common 的org.apache.hadoop.io.serializer.JavaSerializationl 类。WritableSerialization 和AvroReflectSerialization 也有类似的实现。

© 著作权归作者所有

政委007
粉丝 10
博文 15
码字总数 15843
作品 0
洛阳
程序员
私信 提问
hadoop深入研究:(十三)——序列化框架

转载请写明来源地址:http://blog.csdn.net/lastsweetop/article/details/9376495 所有源码在github上,https://github.com/lastsweetop/styhadoop 框架简介 MapReduce仅仅可以支持Writable做......

lastsweetop
2013/07/22
0
0
hadoop 023.0与hadoop 1.0 io.serializable分析

hadoop升级到0.23.0和1.0版本后,其IO底层除了自己实现的Writable序列化后,还增加了一个io.serializer包,该包提供了一种可插拔的持久化框架(Pluggable Serialization Framework)。之所以说...

tuzibuluo
2012/01/01
426
0
【hadoop】18.MapReduce-序列化

简介 序列化就是把内存中的对象,转换成字节序列(或其他数据传输协议)以便于存储(持久化)和网络传输。 反序列化就是将收到字节序列(或其他数据传输协议)或者是硬盘的持久化数据,转换成...

Areya
01/12
12
0
hadoop深入研究:(十)——序列化与Writable接口

转载请写明来源地址:http://blog.csdn.net/lastsweetop/article/details/9193907 所有源码在github上,https://github.com/lastsweetop/styhadoop 简介 序列化和反序列化就是结构化对象和字...

lastsweetop
2013/07/05
0
0
Hadoop的Jython封装--Happy

Hadoop + Python = Happy Happy 为Jython开发者使用Hadoop框架提供了便利,Happy框架封装了Hadoop的复杂调用过程,让Map-Reduce开发变得更为容易。Happy中的Map-Reduce作业过程在子类happy.H...

匿名
2010/08/10
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

关于ThinkPHP5.1+的Log无法记录SQL调试记录的小经历

项目开发阶段,除了基本编码外,性能也需要实时关注与优化。之前我的大部分项目都是使用ThinkPHP5.0以及ThinkPHP3.2,对于框架提供的日志记录和日志配置都差不多,然后使用ThinkPHP5.1的时候...

北桥苏
39分钟前
2
0
TiDB Binlog 源码阅读系列文章(四)Pump server 介绍

作者: satoru 在 上篇文章 中,我们介绍了 TiDB 如何通过 Pump client 将 binlog 发往 Pump,本文将继续介绍 Pump server 的实现,对应的源码主要集中在 TiDB Binlog 仓库的 pump/server.go...

TiDB
42分钟前
2
0
OSChina 周五乱弹 ——不知道假装开心,装的像么

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 :天黑了 你很忧愁, 你说世界上, 找不到四块五的妞, 行走在凌晨两点的马路上, 你疲倦地拿着半盒黄鹤楼。#今日歌曲推荐# 《四块...

小小编辑
今天
2.5K
19
Windows下学习C语言有哪些集成开发软件?

前言 初学者学习C语言遇到的最大困难想必就是搭建环境了,相当多的初学者就是被搭建环境导致放弃了学习编程,就我自己的经验而言,初学编程不应该受限于环境,使用成熟好用的环境就可以了,之...

Allen5G
昨天
3
0
Hello,Servlet!

Servlet来源 上文说过了servlet是什么,我们从servlet是什么中也可以了解到servlet的来源:servlet是Java的一个类,并且能够运行在web容器上,所以servlet是按照web容器的规范和Java的规范写...

蒙尘
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部