【问题标题】:What are the connections and differences between Hadoop Writable and java.io.serialization?Hadoop Writable 和 java.io.serialization 之间有什么联系和区别?
【发布时间】:2013-05-30 12:45:48
【问题描述】:

要实现Writable接口,可以在Hadoop中序列化对象。那么HadoopWritablejava.io.serialization有什么联系和区别呢?

【问题讨论】:

    标签: java serialization hadoop mapreduce


    【解决方案1】:

    潜在的存储差异:

    Java 可序列化

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

    Hadoop 可写

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


    一些不错的读物:

    对于 Java 可序列化:

    Hadoop 可写

    【讨论】:

    • @Denzel 如果您满意,请点赞并接受答案
    • Java Object Serialization 序列化的元数据不包含字段名和类型。部分 [和不准确] 抄袭 here
    【解决方案2】:

    用道格切割的话:

    Writable 接口与 Serializable 略有不同。 Serializable 不假定存储值的类别是已知的。所以 每个实例都标有其类。对象输出流和 ObjectInputStream 对此进行了一些优化,因此 5 字节句柄 在第一个之后为类的实例编写。但是对象序列 然后不能随机访问 with 句柄,因为它们依赖于 流状态。这使排序等事情变得复杂。

    另一方面,可写假设应用程序知道 预期的班级。应用程序必须能够在 为了调用 readFields()。所以类不需要与每个存储 实例。这会产生相当紧凑的二进制文件, 直接的随机访问和通常更高的性能。

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

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

    您必须通过此thread 一次。

    【讨论】:

      猜你喜欢
      • 2011-09-22
      • 1970-01-01
      • 2017-11-11
      • 1970-01-01
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多