使用Apache Avro进行部分反序列化

时间:2020-10-06 12:55:20

标签: avro

是否可以从使用Apache Avro序列化的大型对象中反序列化字段的子集而无需反序列化所有字段?我正在使用GenericDatumReader,而GenericRecord包含所有字段。

我很确定您无法使用GenericDatumReader来完成此操作,但是我的问题是,鉴于Avro的二进制格式,是否可以实现。

2 个答案:

答案 0 :(得分:1)

从概念上讲,Avro数据的二进制序列化是有序且深度优先的。遍历数据时,记录字段一个接一个地序列化,列表从上至下序列化,依此类推。

在一个对象中,没有用于分隔字段的标记,没有用于标识特定字段的标签,也没有索引二进制数据以帮助快速扫描到特定字段。

根据您的架构,您 可以 编写自定义代码以跳过一些类型的数据……例如, < strong>如果 字段是固定字节的列表,则可以读取列表的大小,然后将数据跳转到下一个字段。这是非常特定的,尽管如此,它不适用于大多数Avro类型(值得注意的是,整数在编码时是可变长度的)。

即使在这种不太可能的情况下,我也不认为Java SDK中有任何有用的帮助器。

简而言之,Avro并非旨在做到这一点,并且在不反序列化整个对象的情况下,您可能不会找到令人满意的方式在Schema上进行投影。如果您有一个集合,那么像Parquet这样的面向列的持久性可能是正确的选择!

答案 1 :(得分:1)

要读取的字段可能首先出现在记录中。在某些情况下,我们只想读取对象的标头字段,而不是随后的完整数据,就可以这样做。

您可以创建仅包含那些第一个字段的“子集”模式,并将其传递给GenericDatumReader。 Avro将对这些字段进行反序列化,之后出现的任何内容都将被忽略,因为该架构不会“知道”该字段。

但是,在您要从记录中间挑选字段的一般情况下,这是行不通的。