AVRO – 序列化
AVRO – 序列化
数据序列化有两个目标 –
-
用于持久存储
-
通过网络传输数据
什么是序列化?
序列化是将数据结构或对象状态转换为二进制或文本形式以通过网络传输数据或存储在某些持久存储上的过程。一旦数据通过网络传输或从持久存储中检索,它需要再次反序列化。序列化称为编组,反序列化称为解组。
Java中的序列化
Java 提供了一种称为对象序列化的机制,其中对象可以表示为字节序列,其中包括对象的数据以及有关对象类型和存储在对象中的数据类型的信息。
序列化对象写入文件后,可以从文件中读取并反序列化。也就是说,表示对象及其数据的类型信息和字节可用于在内存中重新创建对象。
ObjectInputStream和ObjectOutputStream类分别用于在 Java 中序列化和反序列化对象。
Hadoop 中的序列化
通常在像 Hadoop 这样的分布式系统中,序列化的概念用于进程间通信和持久存储。
进程间通信
-
为了在网络中连接的节点之间建立进程间通信,使用了 RPC 技术。
-
RPC 使用内部序列化将消息转换为二进制格式,然后通过网络将其发送到远程节点。在另一端,远程系统将二进制流反序列化为原始消息。
-
RPC 序列化格式要求如下 –
-
紧凑– 充分利用网络带宽,这是数据中心中最稀缺的资源。
-
快速– 由于节点之间的通信在分布式系统中至关重要,因此序列化和反序列化过程应该很快,产生更少的开销。
-
可扩展– 协议随着时间的推移而变化以满足新的需求,因此以受控的方式为客户端和服务器发展协议应该很简单。
-
可互操作– 消息格式应支持用不同语言编写的节点。
-
持久化存储
持久存储是一种数字存储设施,不会因断电而丢失数据。文件、文件夹、数据库是持久存储的例子。
可写接口
这是 Hadoop 中的接口,它提供了序列化和反序列化的方法。下表描述了这些方法 –
S.No. | 方法和说明 |
---|---|
1 |
void readFields(DataInput in) 此方法用于反序列化给定对象的字段。 |
2 |
void write(DataOutput out) 此方法用于序列化给定对象的字段。 |
可写的可比接口
它是Writable和Comparable接口的组合。该接口继承了Hadoop的Writable接口和Java的Comparable接口。因此它提供了数据序列化、反序列化和比较的方法。
S.No. | 方法和说明 |
---|---|
1 |
int compareTo(class obj) 此方法将当前对象与给定对象 obj 进行比较。 |
除了这些类之外,Hadoop 还支持许多实现 WritableComparable 接口的包装类。每个类都包装一个 Java 原始类型。Hadoop 序列化的类层次结构如下 –
这些类对于在 Hadoop 中序列化各种类型的数据很有用。例如,让我们考虑IntWritable类。让我们看看这个类是如何用于在 Hadoop 中序列化和反序列化数据的。
可写类
此类实现Writable、Comparable和WritableComparable接口。它在其中包装了一个整数数据类型。此类提供用于序列化和反序列化整数类型数据的方法。
构造函数
S.No. | 概括 |
---|---|
1 | 可写() |
2 | IntWritable(int值) |
方法
S.No. | 概括 |
---|---|
1 |
int get() 使用此方法,您可以获得当前对象中存在的整数值。 |
2 |
void readFields(DataInput in) 此方法用于反序列化给定DataInput对象中的数据。 |
3 |
void set(int value) 该方法用于设置当前IntWritable对象的值。 |
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类的对象传递给它。
-
使用IntWritable 类的readFields()方法反序列化DataInputStream对象中的数据。
-
反序列化的数据将存储在 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 的序列化能够通过重用 Writable 对象来减少对象创建开销,这是 Java 的本机序列化框架无法实现的。
Hadoop序列化的缺点
要序列化 Hadoop 数据,有两种方法 –
-
您可以使用Hadoop 的本机库提供的Writable类。
-
您还可以使用以二进制格式存储数据的序列文件。
这两种机制的主要缺点是Writables和SequenceFiles只有一个 Java API,不能用任何其他语言编写或读取它们。
因此,在Hadoop中使用上述两种机制创建的任何文件都无法被任何其他第三方语言读取,这使得Hadoop成为一个有限的盒子。为了解决这个缺点,Doug Cutting 创建了Avro,这是一种独立于语言的数据结构。