2013-02-25 59 views
0

我感觉ByteArrayOutputStream不是有效的内存,因为它的所有内容都存储在内存中。从大字节阵列输出队列了解Avro反序列化

同样,在大型流上调用toByteArray似乎是“尺度不佳”。

那么,为什么在汤姆怀特的书中的实例的实例Hadoop: the Definitive Guide使用这两个:

ByteArrayOutputStream out = new ByteArrayOutputStream; 
    Decoder decoder = DecoderFactory().defaultFactory().createBinaryDecoder(out.toByteArray(), null); 

不是“大数据”的Avro的规范?我错过了什么?

编辑1:我正在尝试做什么 - 说我通过websocket流avros。如果我想对多个记录进行反序列化,那么这个例子会是什么样子,而不仅仅是它自己的ByteArrayOutoputStream

有没有更好的方法提供BinaryDecoder一个字节[]?或者也许是一种不同类型的流?或者我应该每个流发送1条记录,而不是加载多条记录的流?

+0

如果您具体说明您计划用Avro做什么,那么您的问题会更容易回答。 – 2013-02-25 08:48:27

+0

长长的故事是,我正在扩展[Salat-Avro](https://github.com/Banno/salat-avro)以支持从Avro数据文件序列化Scala案例类。我试图实现数据文件和内存中序列化的方法之间的一致性。 对于大型数据文件,我可以高效地反序列化avros,因为DataFileReader是遍历记录的**迭代器**,并且不会将评估保留在内存中。与数据文件相反,内存中的反序列化不是通过迭代器完成的,而是通过反复调用数据源上的函数评估。 – 2013-02-25 22:40:55

+0

更长的故事是,对于少量记录来说,“重复调用函数”是没有问题的,因为我可以通过'函数的结果产生'Stream'。但随着记录数量的增加,由于内存使用的原因,“Stream”变得不切实际。可悲的是,'Iterator'与'cons'没有什么相似之处,我想知道该怎么做,当我注意到问题中的规范示例可能不支持大量记录时。 – 2013-02-25 22:59:58

回答

0

ByteArrayOutputStream在处理像小到中等图像或固定大小的请求/响应这样的小对象时很有意义。它存储在内存中,不会触及磁盘,因此可以提高性能。将它用于1 TerraByte的数据没有任何意义。可能这是为了保持书中的一个例子小而独立,以避免偏离主要观点。


编辑︰现在,我看到你的去哪里我会寻找设置管道。从流中取出一条消息(所以我假设你可以从HTTP对象中获取InputStream),并使用无内存方法处理它,或者将它放在队列中并使线程池使用内存处理队列无方法。所以对此的要求是:1)能够检测Avro消息之间的边界,并将它们从流中拉出并具有解码方法。

解码的方式似乎是将每个消息的字节读取到一个字节数组中,并将其传递给您的BinaryDecoder(找到消息边界后)。

+0

感谢您的有益回应。 – 2013-02-26 09:42:15