Hadoop Writable和java.io.serialization之间有什么联系和区别?

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

底层存储差异:

Java Serializable

Serializable不假设存储值的类是已知的,并且标记具有其类的实例,即。 它写入有关对象的元数据,包括类名,字段名和类型,以及它的超类。 ObjectOutputStream和ObjectInputStream稍微优化了这一点,因此在第一个类之后为类的实例编写了5个字节的句柄。 但是随后无法随机访问带句柄的对象序列,因为它们依赖于流状态。 这使排序变得复杂。

Hadoop可写

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


一些好的读物:

对于Java Serializable:

Hadoop可写

用Doug Cutting的话来说:

Writable接口与Serializable略有不同。 Serializable不假定存储值类是已知的。 所以每个实例都用它的类标记。 ObjectOutputStream和ObjectInputStream稍微优化了这一点,因此在第一个类之后为类的实例编写了5个字节的句柄。 但是随后无法随机访问带句柄的对象序列,因为它们依赖于流状态。 这使排序变得复杂。

另一方面,可写入假定应用程序知道预期的类。 应用程序必须能够创建一个实例才能调用readFields()。 所以这个类不需要与每个实例一起存储。 这导致更加紧凑的二进制文件,直接的随机访问和通常更高的性能。

可以说Hadoop可以使用Serializable。 对于序列化对性能至关重要的每个类,可以覆盖writeObject或writeExternal。 (MapReduce是非常i / o密集型的,因此几乎每个类的序列化都是性能关键。)可以实现ObjectOutputStream.writeObjectOverride()和ObjectInputStream.readObjectOverride()以使用更紧凑的表示,例如,不需要标记每个具有类的文件中的顶级实例。 这可能需要至少与Haddop在Writable,ObjectWritable等中的代码一样多,并且代码会更复杂一些,因为它会尝试解决不同的打字模型。 但它可能具有更好的内置版本控制的优势。 或者是吗?

Serializable的版本机制是让类定义一个名为serialVersionUID的静态。 这允许人们防止不兼容的更改,但不容易允许实现后向兼容性。 为此,应用程序必须明确处理版本。 它必须以特定于类的方式推断在阅读时编写的版本,以决定要做什么。 但Serializeable的版本机制不支持这个或多于或少于Writable。

你必须经历一次这个主题 。