2013-08-01 49 views
1

我们正在评估avro v/s节俭存储。在这一点上Avro似乎是我们的选择,但是文档声明模式在序列化时与数据一起存储,是否有办法避免这种情况,因为我们既生产又消费数据,我们想看看是否我们可以避免序列化模式,并且序列化数据与模式的大小差异远大于没有模式的数据?Avro模式存储

回答

0

我敢肯定,您将始终需要架构与数据一起存储。这是因为Avro会在读取和写入.avro文件时使用它。

根据http://docs.oracle.com/cd/NOSQL/html/GettingStartedGuide/avroschemas.html

您应用一个模式来使用的Avro绑定的Oracle NoSQL数据库记录的值部分。这些绑定用于在写入值之前序列化值,并在读取值后对值进行反序列化。这些绑定的使用要求您的应用程序使用Avro数据格式,这意味着每个存储值都与一个模式关联。

就尺寸差异而言,您只需存储一次模式,因此在大型计划中,它并没有太大的区别。我的模式占用了105.5KB(这是一个非常大的模式,你不应该那么大),每个序列化的值需要3.3KB。我不知道的区别是什么不仅仅是数据的原始JSON,但根据该链接我张贴:

每个值存储不超过一个小型的内部架构的标识符之外的任何元数据,1间和4个字节大小。

但我相信可能只是单一的简单值。

这是在HDFS为我顺便说一句。

0

感谢JGibel,我们的数据最终最终会以HDFS结尾,并且对象容器文件格式确保模式仅作为文件头被写入。

对于HDFS以外的用途,我错误地认为该架构将附加到每个编码数据,但并非如此,这意味着您需要该架构对其进行反序列化,但是序列化数据不必将模式字符串附加到它。

E.g.

DatumWriter<TransactionInfo> eventDatumWriter = new SpecificDatumWriter<TransactionInfo>(TransactionInfo.class); 

TransactionInfo t1 = getTransaction(); 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
BinaryEncoder becoder = EncoderFactory.get().binaryEncoder(baos, null); 
eventDatumWriter.setSchema(t1.getSchema()); 
eventDatumWriter.write(t1, becoder); 
becoder.flush(); 
+0

很高兴,如果我能够帮助清理任何东西。如果你发现其他东西,请更新! – JGibbers

0

对派对稍迟,但实际上并不需要将实际模式存储在每条记录中。但是,您需要从每个记录的序列化格式中返回原始模式。

因此,您可以使用模式存储+自定义序列化器来编写avro记录内容和模式标识。读取后,您可以读回该架构ID,从架构存储中检索该架构,然后使用该架构来重新水化记录内容。如果模式存储是远程的,则使用本地高速缓存的奖励点。

这正是Oracle's NoSQL DB以存储高效方式管理模式(它也可以在AGPL许可下使用)的方法。

完全披露:目前和以前从未受雇于Oracle或Sun,或曾在上述商店工作。刚刚碰到它最近:)