Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix TextIO not fully reading a GCS file when decompressive transcoding happens #33384

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

shunping
Copy link
Contributor

@shunping shunping commented Dec 15, 2024

When decompressive transcoding occurs, the size returned from metadata (i.e. the gzipped file size) does not match the size of the content returned (i.e. original data size). This causes data loss problem. In this case, we force the source to be unsplittable to ensure all its content is read.

To address this, we leverage the GCS client library's ability to retrieve raw data, even when the object meets the criteria for decompressive transcoding. By setting raw_download=True when initializing the BlobReader, we ensure the complete data is retrieved

This change should not impact performance. The GCS client library already retrieves raw data from GCS and performs any necessary decompression client-side, mimicking the effects of server-side decompressive transcoding. Therefore, the decompression workload always occurs on the client side, which is consistent both before and after the fix.

fixes #31040


Thank you for your contribution! Follow this checklist to help us incorporate your contribution quickly and easily:

  • Mention the appropriate issue in your description (for example: addresses #123), if applicable. This will automatically add a link to the pull request in the issue. If you would like the issue to automatically close on merging the pull request, comment fixes #<ISSUE NUMBER> instead.
  • Update CHANGES.md with noteworthy changes.
  • If this contribution is large, please file an Apache Individual Contributor License Agreement.

See the Contributor Guide for more tips on how to make review process smoother.

To check the build health, please visit https://github.com/apache/beam/blob/master/.test-infra/BUILD_STATUS.md

GitHub Actions Tests Status (on master branch)

Build python source distribution and wheels
Python tests
Java tests
Go tests

See CI.md for more information about GitHub Actions CI or the workflows README to see a list of phrases to trigger workflows.

For GCS, we determine the splittability based on whether the file
meets decompressive transcoding criteria.

When decompressive transcoding occurs, the size returned from
metadata (gzip file size) does not match the size of the content
returned (original data). In this case, we set the source to
unsplittable to ensure all its content is read.
@shunping shunping marked this pull request as draft December 15, 2024 05:14
Copy link

codecov bot commented Dec 15, 2024

Codecov Report

Attention: Patch coverage is 52.63158% with 9 lines in your changes missing coverage. Please review.

Project coverage is 57.39%. Comparing base (d7502fa) to head (40f9a6d).
Report is 27 commits behind head on master.

Files with missing lines Patch % Lines
sdks/python/apache_beam/io/gcp/gcsfilesystem.py 14.28% 6 Missing ⚠️
sdks/python/apache_beam/io/filebasedsource.py 50.00% 2 Missing ⚠️
sdks/python/apache_beam/io/gcp/gcsio.py 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##             master   #33384   +/-   ##
=========================================
  Coverage     57.38%   57.39%           
  Complexity     1475     1475           
=========================================
  Files           973      973           
  Lines        154978   154997   +19     
  Branches       1076     1076           
=========================================
+ Hits          88939    88956   +17     
- Misses        63829    63831    +2     
  Partials       2210     2210           
Flag Coverage Δ
python 81.27% <52.63%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

sdks/python/apache_beam/io/filebasedsource.py Outdated Show resolved Hide resolved
@@ -945,3 +945,6 @@ def report_lineage(self, path, unused_lineage, level=None):
Unless override by FileSystem implementations, default to no-op.
"""
pass

def check_splittability(self, path):
return True
Copy link
Member

Choose a reason for hiding this comment

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

This should probably not always be true. If this is a default, perhaps it should not have a default but be abstract and we implement for various filesystems. If it is the default, comment so we understand that is why it ignores the argument.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The line has been removed in the new change.

def check_splittability(self, path):
try:
file_metadata = self._gcsIO()._status(path)
if file_metadata.get('content_encoding', None) == 'gzip':
Copy link
Member

Choose a reason for hiding this comment

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

Doesn't the content-type also have to be a particular thing in addition to the content-encoding being set to gzip?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The line has been removed in the new change.

@shunping shunping marked this pull request as ready for review January 4, 2025 13:22
@shunping shunping requested a review from kennknowles January 4, 2025 13:22
Copy link
Contributor

github-actions bot commented Jan 4, 2025

Checks are failing. Will not request review until checks are succeeding. If you'd like to override that behavior, comment assign set of reviewers

# object meets the criteria of decompressive transcoding
# (https://cloud.google.com/storage/docs/transcoding).
super().__init__(
blob, chunk_size=chunk_size, retry=retry, raw_download=raw_download)
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good question and that is a valid concern.

The raw_download is included as one of the valid download parameters within the kwargs:

Let me ask the devs of the GCS lib about what is their plan for that API.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just confirmed it is a stable API, and the devs of the library will update their doc to address that.

Copy link
Member

@kennknowles kennknowles left a comment

Choose a reason for hiding this comment

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

The change is so simple now. Nice! If the GCS client library breaks us later, then we can issue an update, but I just wanted to ask if it was going to be stable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: ReadAllFiles does not fully read gzipped files from GCS
2 participants