<>定义

序列化是将结构化对象转换为字节流以通过网络传输或写入持久存储的过程。
反序列化是将字节流转换回一系列结构化对象的逆过程。
序列化用于分布式数据处理的两个截然不同的领域:进程间通信和持久存储。

Hadoop 大量使用网络传输来执行其作业。Doug Cut(Hadoop 的创建者)在他的一篇博文中解释说,java.io.Serializable对
Hadoop 的需求来说太重了,因此开发了一个新接口:Writable。您需要从映射器发送到减速器或作为输出的每个对象都必须实现此接口,以使 Hadoop
从/向集群中的节点传输数据。

在 Hadoop 中,系统中节点之间的进程间通信是使用远程过程调用 (RPC) 实现的。RPC
协议使用序列化将消息转换为二进制流发送到远程节点,然后远程节点将二进制流反序列化为原始消息。
一般来说,RPC 序列化格式应该是:

紧凑:有效利用网络带宽。
快速:预计序列化和反序列化过程的性能开销非常小。
可扩展:适应新的变化和要求。
可互操作:格式需要设计为支持以不同语言编写到服务器的客户端。

假设为持久存储选择的数据格式与序列化框架有不同的要求。毕竟,RPC 的生命周期不到一秒,而持久数据可能在写入后数年才能读取。但事实证明,RPC
序列化格式的四个理想属性对于持久存储格式也至关重要。

Hadoop 使用自己的序列化格式,称为Writables。它当然紧凑且快速,但从 Java 以外的语言中扩展或使用并不那么容易。

<>Writable

Writable 接口有两种方法——一种用于写入,一种用于读取。write方法将其状态写入 DataOutput 二进制流,readFields方法从
DataInput 二进制流中读取其状态。
package org.apache.hadoop.io; import java.io.DataOutput; import java.io.
DataInput; import java.io.IOException; public interface Writable { void write(
DataOutput out) throws IOException; void readFields(DataInput in) throws
IOException; }
让我们看看我们可以用特定的 Writable 做什么。我们将使用IntWritable,它是 Java int
的包装器。我们可以通过两种方式创建和设置它的值: - 使用 set 方法:
IntWritable writable = new IntWritable(); writable.set(57);
另一种方法是使用采用整数值的构造函数:
IntWritable writable = new IntWritable(57);
现在让我们通过编写一个辅助方法来理解上述内容,该方法将 java.io.ByteArrayOutputStream 包装在
java.io.DataOutputStream 中以捕获序列化流中的字节:
public static byte[] serialize(Writable writable) throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream(); DataOutputStream
dataOut= new DataOutputStream(outStream); writable.write(dataOut); dataOut.close
(); return outStream.toByteArray(); }
好的,既然我们了解了序列化,让我们尝试反序列化:
public static byte[] deserialize(Writable writable, byte[] bytes) throws
IOException { ByteArrayInputStream inStream = new ByteArrayInputStream(bytes);
DataInputStream dataIn = new DataInputStream(inStream); writable.readFields(
dataIn); dataIn.close(); return bytes; }

技术
今日推荐
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:766591547
关注微信