如何在关闭ParquetWriter对象并将其写入磁盘之前获取其内存大小?

3
我正在从流中读取Avro消息,并使用parquet.hadoop.ParquetWriter将它们写入Parquet文件。我希望输出文件的大小超过一个阈值。问题在于,ParquetWriter会将所有内容存储在内存中,并且只有在关闭writer时才将其写入磁盘。根据Parquet文档,数据以最终格式写入内存对象,这意味着内存中对象的大小与磁盘上的最终大小相同。我的问题是如何获取内存中已写入数据的大小,以便决定何时关闭writer?
我尝试使用我写入ParquetWriter的Avro消息的字节大小作为Parquet writer文件大小的估计,但由于Parquet存储数据的不同方式(列格式),所以那与parquet writer的大小非常不同。以下是我做的伪代码:
    ParquetWriter parquetWriter = new ParquetWriter(..., BLOCK_SIZE, PAGE_SIZE);    
    long bytesWrittenSofar = 0;

    public long getLength(){
        return bytesWrittenSofar;
    }
    public void write(org.apache.avro.generic.GenericRecord record){
        parquetWriter.write(record);
        bytesWrittenSofar += avroToBytes(record).length;
    }

    public static byte[] avroToBytes(GenericRecord record){
        GenericDatumWriter<GenericRecord> writer =
            new GenericDatumWriter<GenericRecord>(record.getSchema());
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(out, null);
        writer.write(record, encoder);
        encoder.flush();
        out.close();
        return out.toByteArray();
    } 

事实证明,我从getLength()获取的值与parquet文件的实际文件大小非常不同。我知道模式将添加到文件的末尾,但那很小。只是为了给你一个想法,当getLength()报告130MB时,实际文件大小只有80MB。

2个回答

0
这很可能是 API 的后期添加之一,在问题编写时还不可用。
方法 ParquetWriter#getDataSize() 应该能够给你所需的内容。

0

我没有找到访问ParquetWriter使用的内存的方法。相反,我最终通过对上传文件大小和写入记录数进行分析来解决了这个问题。利用以前的数据并计算当前文件中写入的记录数,我估计了正在进行中的文件的文件大小。这种方法比其他任何尝试都更接近真实的文件大小。然而,它高度依赖于应用程序和您编写的记录的变化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接