Saya membaca pesan Avro dari aliran dan menuliskannya ke dalam file Parket menggunakan parquet.hadoop.ParquetWriter. Saya mencoba agar ukuran file keluaran di atas batas ambang batas. masalahnya adalah ParquetWriter menyimpan semuanya di memori dan hanya menuliskannya ke disk di akhir ketika penulis ditutup. Berdasarkan dokumentasi Parket, data ditulis ke dalam objek memori dalam format akhir, artinya ukuran objek di memori sama dengan ukuran akhir pada disk. Pertanyaan saya adalah bagaimana cara mendapatkan ukuran data tertulis di memori untuk memutuskan penutupan penulis?
Saya mencoba menggunakan ukuran byte pesan avro yang saya tulis ke ParquetWriter sebagai perkiraan ukuran file penulis Parket tetapi itu sangat berbeda dengan ukuran penulis parket karena cara parket menyimpan data yang berbeda (format kolom). Inilah kode semu untuk apa yang saya lakukan:
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();
}
Ternyata nilai yang saya dapatkan dari getLength() sangat berbeda dengan ukuran file parket sebenarnya. Saya tahu bahwa skema akan ditambahkan di akhir file tapi itu sangat kecil. Sekadar memberi gambaran, Ketika getLength() melaporkan 130MB, ukuran file sebenarnya hanya 80MB.