ストリームから Avro メッセージを読み取り、parquet.hadoop.ParquetWriter を使用してそれらを Parquet ファイルに書き込んでいます。出力ファイルのサイズをしきい値の制限より大きくしようとしています。問題は、ParquetWriter がすべてをメモリに保持し、ライターが閉じられたときに最後にのみディスクに書き出すことです。Parquet のドキュメントに基づいて、データは最終的な形式でメモリ オブジェクトに書き込まれます。つまり、メモリ内のオブジェクトのサイズはディスク上の最終的なサイズと同じです。私の質問は、ライターを閉じるかどうかを決定するために、メモリに書き込まれたデータのサイズを取得する方法です。
ParquetWriter ファイル サイズの見積もりとして、ParquetWriter に書き込む avro メッセージのバイト サイズを使用してみましたが、寄木細工のデータの格納方法 (列形式) が異なるため、これは寄木細工ライターのサイズとは大きく異なります。私がやったことの擬似コードは次のとおりです。
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() から取得した値は、寄木細工のファイルの実際のファイル サイズとは大きく異なることがわかりました。スキーマがファイルの最後に追加されることはわかっていますが、それは非常に小さいです。参考までに、getLength() が 130MB を報告した場合、実際のファイル サイズはわずか 80MB です。