Hadoop Writable和java.io.serialization之间有哪些联系和区别?

6

要实现Writable接口,对象可以在Hadoop中进行序列化。那么Hadoop Writablejava.io.serialization之间的联系和区别是什么?

2个回答

16

底层存储差异:

Java Serializable

Serializable不假设已知存储值的类,并将实例标记为其类,即写入关于对象的元数据,其中包括类名,字段名称和类型以及其超类。 ObjectOutputSream和ObjectInputStream对此进行了一定的优化,因此在第一次之后,对于该类的实例,会写入5字节的句柄。但是使用句柄的对象序列不能随机访问,因为它们依赖于流状态。这使得像排序之类的事情变得更加复杂。

Hadoop Writable

定义“Writable”时,您知道预期的类。因此,在反序列化时,您知道预期的内容,所以Writables不会将其类型存储在序列化表示中。例如,如果输入键是LongWritable,则要求空的LongWritable实例从输入数据流中填充自身。由于不需要存储元信息(类名、字段及其类型、超类),这导致二进制文件更紧凑,直接的随机访问和更高的性能。


一些好读物:

Java Serializable:

Hadoop Writable


@Denzel 如果您对此满意,请点赞并接受答案。 - Tejas Patil
Java对象序列化序列化的元数据不包括字段名称和类型。部分[不准确]抄袭自此处 - user207421

4
根据Doug Cutting的说法:
Writable接口与Serializable有微妙的不同之处。Serializable不假设存储值的类是已知的,因此每个实例都带有其类。ObjectOutputStream和ObjectInputStream在某种程度上进行了优化,因此对于第一次出现的类的实例,将编写5字节的句柄。但是,具有句柄的对象序列无法随机访问,因为它们依赖于流状态。这使得诸如排序之类的事情变得更加复杂。
另一方面,Writable假定应用程序知道预期的类。应用程序必须能够创建实例才能调用readFields()。因此,类不需要与每个实例一起存储。这会导致更紧凑的二进制文件、直接的随机访问和通常更高的性能。
可以说Hadoop可以使用Serializable。可以为每个序列化性能关键的类覆盖writeObject或writeExternal。(MapReduce非常I/O密集,因此几乎每个类的序列化都是性能关键的。)可以实现ObjectOutputStream.writeObjectOverride()和ObjectInputStream.readObjectOverride(),以使用更紧凑的表示形式,例如不需要将文件中每个顶级实例标记为其类。这可能需要至少与Writable、ObjectWritable等中Haddop的代码一样多,而且代码会更加复杂,因为它试图解决不同的键入模型问题。但它可能具有更好的内置版本控制优势。或者呢?
Serializable的版本机制是让类定义一个静态命名的serialVersionUID。这允许防止不兼容的更改,但不容易实现向后兼容性。为此,应用程序必须明确处理版本。它必须以特定于类的方式推理写入时的版本,以决定要执行什么操作。但是,Serializable的版本机制与Writable一样支持此功能。

你必须阅读一遍这个thread


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接