AVRO - 序列化

数据被序列化为两个目标 :

  • 持久存储

  • 通过网络传输数据

什么是序列化?

<序列化是将数据结构或对象状态转换为二进制或文本形式以通过网络传输数据或存储在某些持久存储上的过程.一旦数据通过网络传输或从持久存储中检索,就需要再次反序列化.序列化被称为编组,反序列化被称为解组.

Java中的序列化

Java提供了一种称为对象序列化的机制,其中对象可以表示为包含对象数据的字节序列,以及有关对象类型和对象中存储的数据类型的信息.

将序列化对象写入文件后,可以从文件中读取并反序列化.也就是说,表示对象及其数据的类型信息和字节可用于在内存中重新创建对象.

ObjectInputStream ObjectOutputStream 类用于分别在Java中序列化和反序列化对象.

Hadoop中的序列化

通常在像Hadoop这样的分布式系统中,概念序列化用于进程间通信持久存储.

进程间通信

  • 为了建立网络中连接的节点之间的进程间通信,使用了RPC技术.

  • RPC使用内部序列化将消息转换为二进制格式,然后通过网络将其发送到远程节点.在另一端,远程系统将二进制流反序列化为原始消息.

  • RPC序列化格式必须如下 :

    • 紧凑 : 为了充分利用网络带宽,这是数据中心中最稀缺的资源.

    • 快速 : 由于节点之间的通信在分布式系统中至关重要,因此序列化和反序列化过程应该很快,产生的开销更少.

    • 可扩展 : 协议随着时间的推移而变化以满足新的要求,因此对于客户端和服务器来说,以受控方式发展协议应该是直截了当的.

    • 可互操作 : 消息格式应该支持用不同语言编写的节点.

永久存储

永久存储是一种数字存储设施,不会因丢失
电源而丢失数据.文件,文件夹,数据库是持久存储的示例.

可写接口

这是Hadoop中的接口,它提供了序列化和反序列化的方法.下表描述了方法 :

S.No.方法和描述
1

void readFields(DataInput in)

此方法用于反序列化给定对象的字段.

2

void write(DataOutput out)

此方法用于序列化给定对象的字段.

可写的可比接口

它是可写可比较接口的组合.该接口继承了Hadoop的 Writable 接口以及Java的 Comparable 接口.因此,它提供了数据序列化,反序列化和比较的方法.

S.No.方法和描述
1

int compareTo(class obj)

此方法将当前对象与给定对象obj进行比较.

除了这些类之外,Hadoop还支持许多实现WritableComparable接口的包装类.每个类都包装一个Java原始类型. Hadoop序列化的类层次结构在下面给出 :

Hadoop Serialization Hierarchy

这些类对于在Hadoop中序列化各种类型的数据很有用.例如,让我们考虑 IntWritable 类.让我们看一下这个类是如何用来序列化和反序列化Hadoop中的数据的.

IntWritable Class

这个类实现了可写,可比较, WritableComparable 接口.它包含一个整数数据类型.此类提供用于序列化和反序列化整数类型数据的方法.

构造函数

S.No.摘要
1 IntWritable()
2 IntWritable(int value)

方法

S.No.摘要
1

int get()

使用此方法可以获得当前对象中存在的整数值.

2

void readFields(DataInput in)

此方法用于反序列化给定 DataInput 对象中的数据.

3

void set(int value)

使用此方法设定价值当前 IntWritable 对象的e.

4

void write(DataOutput out)

此方法用于将当前对象中的数据序列化为给定的 DataOutput 对象.

在Hadoop中序列化数据

下面讨论序列化整数类型数据的过程.

  • 实例化 IntWritable 通过在其中包装整数值.

  • 实例化 ByteArrayOutputStream 类.

  • 实例化 DataOutputStream 类并将 ByteArrayOutputStream 类的对象传递给它.

  • 使用 write()方法在IntWritable对象中序列化整数值.此方法需要DataOutputStream类的对象.

  • 序列化数据将存储在字节数组对象中,该对象作为参数传递给 DataOutputStream 实例化时的类.将对象中的数据转换为字节数组.

示例

以下示例说明如何序列化Hadoop中的整数类型的数据 :

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;

public class Serialization {
   public byte[] serialize() throws IOException{
		
      //Instantiating the IntWritable object
      IntWritable intwritable = new IntWritable(12);
   
      //Instantiating ByteArrayOutputStream object
      ByteArrayOutputStream byteoutputStream = new ByteArrayOutputStream();
   
      //Instantiating DataOutputStream object
      DataOutputStream dataOutputStream = new
      DataOutputStream(byteoutputStream);
   
      //Serializing the data
      intwritable.write(dataOutputStream);
   
      //storing the serialized object in bytearray
      byte[] byteArray = byteoutputStream.toByteArray();
   
      //Closing the OutputStream
      dataOutputStream.close();
      return(byteArray);
   }
	
   public static void main(String args[]) throws IOException{
      Serialization serialization= new Serialization();
      serialization.serialize();
      System.out.println();
   }
}

反序列化Hadoop中的数据

反序列化整数的过程下面讨论数据类型 :

  • 通过包装整数值来实例化 IntWritable 类它.

  • 实例化 ByteArrayOutputStream 类.

  • 实例化 DataOutputStream 类并将 ByteArrayOutputStream 类的对象传递给它.

  • 反序列化对象中的数据 DataInputStream 使用IntWritable类的 readFields()方法.

  • 反序列化的数据将存储在IntWritable类的对象.您可以使用此类的 get()方法检索此数据.

示例

以下示例显示如何反序列化Hadoop中的整数类型数据 :

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;

import org.apache.hadoop.io.IntWritable;

public class Deserialization {

   public void deserialize(byte[]byteArray) throws Exception{
   
      //Instantiating the IntWritable class
      IntWritable intwritable =new IntWritable();
      
      //Instantiating ByteArrayInputStream object
      ByteArrayInputStream InputStream = new ByteArrayInputStream(byteArray);
      
      //Instantiating DataInputStream object
      DataInputStream datainputstream=new DataInputStream(InputStream);
      
      //deserializing the data in DataInputStream
      intwritable.readFields(datainputstream);
      
      //printing the serialized data
      System.out.println((intwritable).get());
   }
   
   public static void main(String args[]) throws Exception {
      Deserialization dese = new Deserialization();
      dese.deserialize(new Serialization().serialize());
   }
}

Hadoop优于Java序列化的优势

Hadoop基于可写的序列化能够通过重用Writable对象来减少对象创建开销,这是Java的本机序列化框架无法实现的.

Hadoop序列化的缺点

要序列化Hadoop数据,有两种方式和减号;

  • 您可以使用 Writable 类,由Hadoop的本机库提供.

  • 您还可以使用序列文件以二进制格式存储数据.

这两种机制的主要缺点是 Writables SequenceFiles 只有一个Java API,它们不能用任何其他语言编写或读取.

因此,在Hadoop中使用上述两种机制创建的任何文件都无法被任何其他第三语言读取,这使得Hadoop成为有限的盒子.为了解决这个缺点,Doug Cutting创建了 Avro,这是一种语言无关的数据结构.