【发布时间】:2015-04-30 23:08:38
【问题描述】:
我正在尝试读取保存在 hdfs 中的 hadoop 中的 avro 格式数据。 但是我看到的大多数示例都要求我们将模式解析为作业.. 但我无法理解这个要求。我使用 pig 和 avro,但我从未传递过模式信息。
所以,我想我可能遗漏了一些东西。基本上,如果我没有架构信息,那么在 hadoop mapreduce 中读取 avro 文件的好方法是什么? 谢谢
【问题讨论】:
我正在尝试读取保存在 hdfs 中的 hadoop 中的 avro 格式数据。 但是我看到的大多数示例都要求我们将模式解析为作业.. 但我无法理解这个要求。我使用 pig 和 avro,但我从未传递过模式信息。
所以,我想我可能遗漏了一些东西。基本上,如果我没有架构信息,那么在 hadoop mapreduce 中读取 avro 文件的好方法是什么? 谢谢
【问题讨论】:
你说得对,Avro 对提前知道类型非常严格。如果您不知道架构,我知道的唯一选择是将其读取为GenericRecord。这是一个关于如何做到这一点的sn-p
public class MyMapper extends extends Mapper<AvroKey<GenericRecord>, NullWritable, ... > {
@Override
protected void map(AvroKey<GenericRecord> key, NullWritable value, Context context) throws IOException, InterruptedException {
GenericRecord datum = key.datum();
Schema schema = datum.getSchema();
Object field1 = datam.get(0);
Object someField = datam.get("someField");
...
}
}
当然,你不会有好的 getter 和 setter,因为 Java 不知道它是什么类型。唯一可用的 getter 按位置或名称检索字段。您必须将结果转换为您知道该字段的类型。如果您不知道,则必须让instanceof 检查所有可能性,因为 Java 是静态编译的(这也是为什么它不像您最初认为您可以访问模式那样有用)。
但是如果您知道它可能是(或应该是)的类型,您可以在从 avsc 生成的类上调用 getSchema()(您希望输入是),创建它的新实例,然后映射从 GenericRecord 中逐个字段到该新对象。这将使您重新访问正常的 Avro 方法。在处理联合、空值和模式版本控制时,这当然会变得更加复杂。
【讨论】: