Skip to content

(WIP) Making compression ratio dynamically calculated based on bytes written - #347

Closed
n3nash wants to merge 1 commit into
apache:masterfrom
n3nash:fix_compression_ratio
Closed

(WIP) Making compression ratio dynamically calculated based on bytes written#347
n3nash wants to merge 1 commit into
apache:masterfrom
n3nash:fix_compression_ratio

Conversation

@n3nash

Copy link
Copy Markdown
Contributor

No description provided.

@n3nash

Copy link
Copy Markdown
ContributorAuthor

@vinothchandar I would like to have a quick discussion on this before you take a pass.

@n3nashn3nash changed the title Making compression ratio dynamically calculated based on bytes written(WIP) Making compression ratio dynamically calculated based on bytes writtenMar 14, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type change here, probably do a rebase?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, done.

@n3nash
n3nashforce-pushed the fix_compression_ratio branch from b30eef8 to f04879eCompareMarch 14, 2018 20:20

@n3nashn3nashMar 14, 2018

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing this helps to call fs.getBytesWritten(file) even after the stream is closed and gives back an exact number of uncompressed bytes written. @vinothchandar

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stream is closed implies that the file (block i think) is fully written?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and so the wrappedStream has the correct number of bytes to return..

@n3nash
n3nashforce-pushed the fix_compression_ratio branch from f04879e to 1437afbCompareMarch 14, 2018 20:25

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can make the DEFAULT be calculated based on maxFileSize.

@n3nash
n3nashforce-pushed the fix_compression_ratio branch from 1437afb to 1cfd36dCompareMarch 14, 2018 20:40
@n3nash
n3nashforce-pushed the fix_compression_ratio branch from 1cfd36d to 7483160CompareMarch 14, 2018 21:12
@ovj

ovj commented Mar 14, 2018

Copy link
Copy Markdown
Contributor

@n3nash Can we check in the underlying OutputStream (by adding wrapper) to see how much is getting written. This will help us to correctly throttle file size.

@n3nash

Copy link
Copy Markdown
ContributorAuthor

@ovj this code actually already does that, the change is just to make sure we can get bytes before the stream is closed.

@vinothchandarvinothchandar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High level: we can go with two approaches
A) Just care about the compressed_size_per_record, based on commit metadata previously
B) Get uncompressed and compressed sizes and determine the compression ratio.. (This PR)

Neither really tackles the case when there is no history/commits to get a sense of the record size.. (correct me if I am missing sth)

I am actually leaning more on doubling down on A (which is what the partitioner uses to pack data today). Is that grossly inaccurate in sizing partitions?

Also can you confirm this has been set..

 // Config to control whether we control insert split sizes automatically based on average record sizes
public static final String COPY_ON_WRITE_TABLE_AUTO_SPLIT_INSERTS = "hoodie.copyonwrite.insert.auto.split";
// its off by default
public static final String DEFAULT_COPY_ON_WRITE_TABLE_AUTO_SPLIT_INSERTS = String.valueOf(false);

writeStatus.getStat().setNumWrites(recordsWritten);
writeStatus.getStat().setNumDeletes(recordsDeleted);
// an estimate of the number of bytes written
writeStatus.getStat().setTotalUncompressedWriteBytes(recordsWritten*averageRecordSize);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

really like to understand how your IDE is setup :).. how come it missed formatting the space between * in this diff, while it changed it everywhere in the other..

we really need to do #287

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stream is closed implies that the file (block i think) is fully written?

new HoodieParquetConfig(writeSupport, CompressionCodecName.GZIP,
config.getParquetBlockSize(), config.getParquetPageSize(),
config.getParquetMaxFileSize(), hoodieTable.getHadoopConf());
config.getParquetMaxFileSize(), hoodieTable.getHadoopConf(), compressionRatioPerRecord(hoodieTable));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will be opened in each executor?

@n3nash

n3nash commented Mar 20, 2018

Copy link
Copy Markdown
ContributorAuthor

@vinothchandar I see few ways to pass information of number of records needed in a partition to create handle :

  1. We can add this to the workload profile and call getpartitioner() before savingWorkloadProfile to the inflight file, but again, each executor will have to read the workload profile..
  2. Expose a setter in the HoodieWriteConfig and set it there and pass it down..
  3. Add it as another value to all method invokations leading to IOHandle..

I personally like 1 over 2 and am not in favor of 3. But I also want to explore the addition of the metric (this PR) which makes things simpler.

@vinothchandar

Copy link
Copy Markdown
Member

Option #4 (lmk what you think)

  • We pull out BucketInfo which is what holds things like fileLocation etc as a top level class
  • We save up the number of records needed to write a file of configure size, when computed once during UpsertPartitioner construction, into BucketInfo (or open to another member in Partitioner itself)
  • We pass BucketInfo from driver to each executor and let it do its thing
  • For createHandle, we directly chop off files based on number of records (which will factor in compression ratio automatically) set in BucketInfo or fallback using a configured compression fraction if not set (i.e initial bulkInsert)

@n3nash

Copy link
Copy Markdown
ContributorAuthor

I'm fine with this approach too. Ideally, I was looking for something that requires less refactor and can be a quick way to fix this compression issue so I can spend time starting to run a dataset end to end, tune the compaction process and move towards running this in prod, hence this PR and my suggested approaches..

@vinothchandar

Copy link
Copy Markdown
Member

Understand where you are coming from. Unfortunately this is not straightforward. If thats your stated short term goal, I suggest just introduce a config for compression ratio, set it as desired and move on..
Would that work?

@n3nash

Copy link
Copy Markdown
ContributorAuthor

Yeah, let me do that for now. Once I start to run some datasets and am able to do validations, I can spend time on this again.

@vinothchandar

Copy link
Copy Markdown
Member

closing for now , keeping the issue open

vinishjail97 pushed a commit to vinishjail97/hudi that referenced this pull request Dec 15, 2023
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@n3nash@ovj@vinothchandar@jianxu