3

ストリームから 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 です。

4

2 に答える 2

0

ParquetWriter が使用するメモリにアクセスする方法が見つかりませんでした。代わりに、アップロードされたファイルのサイズと、そこに書き込まれたレコードの数をプロファイリングすることになりました。以前のデータを使用し、現在のファイルに書き込まれたレコード数を数えることで、現在進行中のファイルのファイル サイズを推定しました。これは、他のどの試行よりも実際のファイル サイズにはるかに近いことが判明しました。ただし、アプリケーションと、作成するレコードのバリエーションに大きく依存します。

于 2015-03-07T01:53:30.877 に答える