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