AVRO 序列化


数据序列化有两个目的:

  • 用于持久存储

  • 通过网络传输数据

什么是序列化?


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

Java中的序列化


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

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

Object输入Stream and Object输出Stream 在 Java 中,类分别用于序列化和反序列化对象。

Hadoop中的序列化


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

进程间通信

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

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

  • RPC序列化格式要求如下:

    • Compact : 充分利用网络带宽,这是数据中心最稀缺的资源。

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

    • 可扩展 : 协议会随着时间的推移而变化以满足新的需求,因此以受控方式为客户端和服务器演进协议应该是直截了当的。

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

持久存储

持久存储是一种数字存储设施,不会随着数据的丢失而丢失数据 电源。文件、文件夹、数据库是持久存储的例子。

可写接口


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

S.No. 方法和描述
1

void readFields(Data输入 in)

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

2

void write(Data输出 out)

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

可写可比接口


它是 Writable and 可比 interfaces. This interface inherits Writable interface of Hadoop as well as 可比 interface of Java. Therefore it provides methods for data serialization, deserialization, and comparison.

S.No. 方法和描述
1

int compareTo(class obj)

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

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

Hadoop Serialization Hierarchy

这些类对于在 Hadoop 中序列化各种类型的数据很有用。例如,让我们考虑 可写的 班级。让我们看看这个类是如何用来序列化和反序列化 Hadoop 中的数据的。

可写类


这个类实现 可写,可比, and 可写可比 interfaces. It wraps an integer data type in it. This class provides methods used to serialize and deserialize integer type of data.

构造函数

S.No. Summary
1 可写()
2 IntWritable(整数值)

Methods

S.No. Summary
1

int get()

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

2

void readFields(Data输入 in)

此方法用于反序列化给定数据中的数据 数据输入 object.

3

void set(int value)

此方法用于设置当前的值 可写的 object.

4

void write(Data输出 out)

该方法用于将当前对象中的数据序列化为给定的 数据输出 object.

在 Hadoop 中序列化数据


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

  • 实例化 可写的 通过在其中包装一个整数值来创建类。

  • 实例化 字节数组输出流 class.

  • 实例化 数据输出流 类并传递对象 字节数组输出流 给它上课。

  • 使用序列化 IntWritable 对象中的整数值 write() 方法。该方法需要一个 Data输出Stream 类的对象。

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

例子

下面的例子展示了如何在 Hadoop 中序列化整数类型的数据:

import java.io.ByteArray输出Stream;
import java.io.Data输出Stream;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;

public class Serialization {
    public byte[] serialize() throws IOException{
		
        // 实例化 IntWritable 对象
        IntWritable intwritable = new IntWritable(12);
   
        // 实例化 ByteArray输出Stream 对象
        ByteArray输出Stream byteoutputStream = new ByteArray输出Stream();
   
        // 实例化 Data输出Stream 对象
        Data输出Stream data输出Stream = new
        Data输出Stream(byteoutputStream);
   
        // 序列化数据
        intwritable.write(data输出Stream);
   
        // 将序列化的对象存储在 bytearray 中
        byte[] byteArray = byteoutputStream.toByteArray();
   
        // 关闭输出流
        data输出Stream.close();
        return(byteArray);
    }
	
    public static void main(String args[]) throws IOException{
        Serialization serialization= new Serialization();
        serialization.serialize();
        System.out.println();
    }
}

反序列化 Hadoop 中的数据


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

  • 实例化 可写的 通过在其中包装一个整数值来创建类。

  • 实例化 字节数组输出流 class.

  • 实例化 数据输出流 类并传递对象 字节数组输出流 给它上课。

  • 反序列化对象中的数据 数据输入流 using 读取字段() IntWritable 类的方法。

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

例子

下面的例子展示了如何在 Hadoop 中反序列化整数类型的数据:

import java.io.ByteArray输入Stream;
import java.io.Data输入Stream;

import org.apache.hadoop.io.IntWritable;

public class Deserialization {

    public void deserialize(byte[]byteArray) throws Exception{
   
        // 实例化 IntWritable 类
        IntWritable intwritable =new IntWritable();
      
        // 实例化 ByteArray输入Stream 对象
        ByteArray输入Stream 输入Stream = new ByteArray输入Stream(byteArray);
      
        // 实例化 Data输入Stream 对象
        Data输入Stream datainputstream=new Data输入Stream(输入Stream);
      
        // 反序列化Data输入Stream中的数据
        intwritable.readFields(datainputstream);
      
        // 打印序列化数据
        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 的序列化能够通过重用 Writable 对象来减少对象创建的开销,这在 Java 的本机序列化框架中是不可能的。

Hadoop序列化的缺点


序列化Hadoop数据有两种方式:

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

  • 你也可以使用 序列文件 它以二进制格式存储数据。

这两种机制的主要缺点是 可写 and 序列文件 只有一个 Java API,它们不能用任何其他语言编写或读取。

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