要实现Writable
接口,可以在Hadoop中序列化对象。那么Hadoop Writable
和java.io.serialization
之间的联系和区别是什么?
答案 0 :(得分:16)
Java Serializable
Serializable不会假设存储值类是已知的,并且标记具有其类的实例,即。它写入有关对象的元数据,包括类名,字段名和类型,以及它的超类。 ObjectOutputStream和ObjectInputStream稍微优化了这一点,因此在第一个类之后为类的实例编写了5个字节的句柄。但是随后无法随机访问带句柄的对象序列,因为它们依赖于流状态。这使排序等事情变得复杂。
Hadoop可写
在定义“可写”时,您知道预期的类。因此,在反序列化时,Writable不会将它们的类型存储在序列化表示中,您知道预期的内容。例如。如果输入键是LongWritable,则要求空的LongWritable实例从输入数据流中填充自身。 由于不需要存储元信息(类名,字段,类型,超类),因此可以生成更紧凑的二进制文件,直接的随机访问和更高的性能。
一些好的读物:
For Java Serializable:
Hadoop Writable
答案 1 :(得分:3)
用Doug Cutting的话来说:
Writable接口与Serializable略有不同。 Serializable不假定已知存储值类。所以 每个实例都标有其类。 ObjectOutputStream和 ObjectInputStream稍微优化了这一点,因此5字节句柄是 为第一个类之后的类实例编写。但对象序列 因为它们依赖,所以随后无法随机访问句柄 流状态。这使排序等事情变得复杂。
另一方面,可写假定应用程序知道 预期的课程。应用程序必须能够在中创建实例 为了调用readFields()。因此,不需要存储每个类 实例。这导致更紧凑的二进制文件, 直接的随机访问和通常更高的性能。
可以说Hadoop可以使用Serializable。可以覆盖writeObject 或序列化为性能的每个类的writeExternal 危急。 (MapReduce是非常i / o密集型的,所以几乎每个类都是 序列化对性能至关重要。)可以实现 ObjectOutputStream.writeObjectOverride()和 ObjectInputStream.readObjectOverride()使用更紧凑 表示,例如,不需要标记每个顶级 具有类的文件中的实例。这可能需要as 至少和Haddop在Writable,ObjectWritable等中的代码一样多, 而代码会有点复杂,因为它会尝试 解决不同的打字模型。但它可能有 更好的内置版本控制的优势。或者是吗?
Serializable的版本机制是让类定义静态 命名为serialVersionUID。这允许人们防范 不兼容的更改,但不容易允许实现 向后兼容性。为此,应用程序必须明确处理 与版本。它必须以特定于阶级的方式推理 阅读时写的版本,决定做什么。但 Serializeable的版本机制不再支持这个或 少于可写。
您必须完成此thread一次。