如何在压缩的avro文件中获取每个avro记录的开始结束和结束?

时间:2015-09-11 17:03:36

标签: java avro

我的问题是这个。我有一个2GB的snappy压缩avro文件,在HDFS上存储了大约1000个avro记录。我知道我可以编写代码来打开这个avro文件"并打印出每个avro记录。我的问题是,有没有一种方法在java中说,打开这个avro文件,遍历每个记录并输出到文本文件"开始位置"和"结束位置"该avro文件中的每条记录都是这样的...我可以进行java函数调用" readRecord(startposition,endposition)"可以采用startposition和endposition快速读出一个特定的avro记录,而不必遍历整个文件?

2 个答案:

答案 0 :(得分:1)

您可以单独压缩每条记录。这不会给你很好的压缩比,但它会随机访问。

我建议使用ZIP或JAR格式。

  • 为每条记录提供一个名义文件名,可以只是一个数字。
  • 将序列化数据作为文件内容写入JAR。

何时需要随机访问

  • 打开JAR
  • 按名称查找条目。
  • 阅读并反序列化。

这将以最有效的方式为每个条目压缩数据。

答案 1 :(得分:1)

我没有时间为您提供现成的实施方案,但我认为我可以为您提供一些提示。

让我们从Avro规范开始:Object Container Files

基本上,Avro文件是一组包含一个或多个记录的自包含块(您可以配置大小块,并且记录永远不会分成两个块)。在每个块的开头,您会找到:

  • 指示此块中对象计数的long。
  • 一个long,表示在应用任何编解码器后,当前块中序列化对象的字节大小
  • 序列化对象。如果指定了编解码器,则会被该编解码器压缩。
  • 文件的16字节同步标记。

文档明确指出" 因此,可以有效地提取或跳过每个块的二进制数据,而无需反序列化内容。块大小,对象计数和同步标记的组合可以检测损坏的块并帮助确保数据完整性。"。

您不能直接寻找特定记录,但您可以寻找给定的块然后迭代其对象。这不完全是你需要的,但似乎足够接近。我相信你不可能比使用Avro容器做得更好。您仍然可以调整块大小以最大限度地限制块内的迭代次数。使用压缩时,它会在块级别应用,因此不会成为问题。

我相信只有公共Avro API(FileDataReader提供seeksync方法等)才能实现此类读者。