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

Add support for compression on gRPC cache #14041

Conversation

AlessandroPatti
Copy link
Contributor

Add support for compressed transfers from/to gRPC remote caches. Tested with bazel-remote 2.13.

Relates to #13344

@google-cla
Copy link

google-cla bot commented Sep 26, 2021

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@google-cla google-cla bot added the cla: no label Sep 26, 2021
@AlessandroPatti
Copy link
Contributor Author

@googlebot I signed it!

@google-cla google-cla bot added cla: yes and removed cla: no labels Sep 26, 2021
@AlessandroPatti AlessandroPatti force-pushed the apatti/cache-bytestream-compression branch 4 times, most recently from a522fc5 to 57f86be Compare September 27, 2021 07:14
Copy link
Member

@coeuvre coeuvre left a comment

Choose a reason for hiding this comment

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

Thanks for the PR!

For reasons, we can't merge PR that contains both non third_party and third_party changes. Can you split third_party changes into another PR?

@benjaminp
Copy link
Collaborator

Note that zstd-jni has a sad history here: #12437, #11968

@AlessandroPatti AlessandroPatti force-pushed the apatti/cache-bytestream-compression branch 2 times, most recently from cc27594 to 90c49c9 Compare September 29, 2021 08:15
@AlessandroPatti
Copy link
Contributor Author

Note that zstd-jni has a sad history here: #12437, #11968

Thank you @benjaminp for pointing that out. @philwo seems like #12437 got reverted, what was the reason of the revert? From #11968, it seems there was an issue with the version of apache commons compress, which is not used here. Can zstd-jni be merged back?

@AlessandroPatti AlessandroPatti force-pushed the apatti/cache-bytestream-compression branch from 90c49c9 to 99d43c5 Compare September 29, 2021 08:32
@philwo
Copy link
Member

philwo commented Sep 29, 2021

seems like #12437 got reverted, what was the reason of the revert?

From the rollback commit: "We're rolling back this feature before cutting Bazel 4.0 LTS, as we can't merge the remaining part in time and are worried that the newly added patched JNI dependency will make it hard for distributions like Debian to accept. Let's revisit this when we find a suitable pure Java version of Zstd."

The only pure Java version I could find was https://github.com/airlift/aircompressor, which still doesn't support Big Endian (and it doesn't look like they care about that). So, we'd be OK with adding zstdlib and zstd-jni now, probably.

Can zstd-jni be merged back?

  • @meteorcloudy @olekw how difficult would this additional dependency be for Debian (it seems like it's currently not packaged, but maybe it could easily be)?
  • We can't accept prebuilt binary JARs (I know we still have some, but we really need to get rid of them) and instead would like to build all dependencies from source. We'd have to replace the checked in JAR files in this PR with instead downloading zstdlib and zstd-jni's sources in our WORKSPACE file, creating BUILD files for them and then using that to build the whole thing from source. I'd love to open-source the BUILD files that we use internally for these two libraries for your reference, let me see whether I can easily do this...
  • @meisterT should have another look at it from a performance / binary size increase perspective then

@meteorcloudy
Copy link
Member

@meteorcloudy @olekw how difficult would this additional dependency be for Debian (it seems like it's currently not packaged, but maybe it could easily be)?

I assume https://github.com/luben/zstd-jni is the repo of this library? Looks like it doesn't have much dependencies and already builds with gradle, so should be easy to package for Debian. But leaving @olekw to confirm.

@AlessandroPatti AlessandroPatti force-pushed the apatti/cache-bytestream-compression branch from 99d43c5 to d86b71e Compare October 13, 2021 21:02
@AlessandroPatti AlessandroPatti requested a review from a team as a code owner October 13, 2021 21:02
@AlessandroPatti AlessandroPatti force-pushed the apatti/cache-bytestream-compression branch 4 times, most recently from 1f82978 to 4250f0f Compare October 14, 2021 09:07
@AlessandroPatti AlessandroPatti force-pushed the apatti/cache-bytestream-compression branch from e8369f5 to 6c13594 Compare October 18, 2021 07:40
@AlessandroPatti
Copy link
Contributor Author

@philwo @coeuvre I've addressed the issues from your comment, could you please have another look? If it looks good, I'll create another PR to merge changes for third-party code first.

Copy link
Member

@philwo philwo left a comment

Choose a reason for hiding this comment

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

This looks great to me, thank you! I'd like someone from @bazelbuild/remote-execution to give an LGTM, too, then we can import this.

@philwo
Copy link
Member

philwo commented Oct 19, 2021

I'll create another PR to merge changes for third-party code first.

In this case I think it should be possible to import the third-party change directly from this PR, so I can try that first once we're ready to merge.

"archive": "v1.5.0-4.zip",
"sha256": "d320d59b89a163c5efccbe4915ae6a49883ce653cdc670643dfa21c6063108e4",
"urls": [
"https://github.com/luben/zstd-jni/archive/v1.5.0-4.zip",
Copy link
Contributor Author

@AlessandroPatti AlessandroPatti Oct 19, 2021

Choose a reason for hiding this comment

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

It might be good to mirror this in mirror.bazel.build. @philwo could you help with that as part of the merge?

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
Member

@coeuvre coeuvre left a comment

Choose a reason for hiding this comment

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

LGTM. @philwo we can start to merge this.

@coeuvre
Copy link
Member

coeuvre commented Nov 4, 2021

The import is almost done except that we use an older zstd-jni version internally which doesn't contain the fix luben/zstd-jni@3d51bdc. So the test streamCanBeDecompressedOneByteAtATime is stuck in an infinite loop.

@AlessandroPatti, while we are waiting for upgrading internal zstd-jni (it's not an easy task and I am afraid that it won't be done soon), is there any workaround we could apply?

@AlessandroPatti
Copy link
Contributor Author

The import is almost done except that we use an older zstd-jni version internally which doesn't contain the fix luben/zstd-jni@3d51bdc. So the test streamCanBeDecompressedOneByteAtATime is stuck in an infinite loop.

@AlessandroPatti, while we are waiting for upgrading internal zstd-jni (it's not an easy task and I am afraid that it won't be done soon), is there any workaround we could apply?

What version are you using internally? I can try to reproduce on my end and see if there is any workaround.
Alternatively, can we disable the test for lower zstd versions (e.g. if (ZstdVersion.VERSION != "1.5.0-4") return;) to make the Pr merge cleanly? As long as the compression does not get enabled, this code path wouldn't get hit internally and it can wait for zstd-jni to be upgraded.

@coeuvre
Copy link
Member

coeuvre commented Nov 5, 2021

We are at luben/zstd-jni@190e4f2 with some custom patches.

Alternatively, can we disable the test for lower zstd versions (e.g. if (ZstdVersion.VERSION != "1.5.0-4") return;) to make the Pr merge cleanly?

SGTM.

@coeuvre
Copy link
Member

coeuvre commented Nov 5, 2021

Imported and waiting for the final review.

Some zstd tests are not tested internally but should be fine since they are always tested on Bazel CI.

@bazel-io bazel-io closed this in 6da8086 Nov 12, 2021
@brentleyjones
Copy link
Contributor

@coeuvre What's your feeling on the risk level of getting this into 5.0?

@coeuvre
Copy link
Member

coeuvre commented Nov 15, 2021

It should be fine to get this into 5.0 since it is guarded by an experimental flag.

coeuvre pushed a commit to coeuvre/bazel that referenced this pull request Nov 15, 2021
Add support for compressed transfers from/to gRPC remote caches with flag --experimental_remote_cache_compression.

Fixes bazelbuild#13344.

Closes bazelbuild#14041.

PiperOrigin-RevId: 409328001
Wyverald pushed a commit that referenced this pull request Nov 15, 2021
* Add patch files for zstd-jni

Partial commit for third_party/*, see #14203.

Closes #14203

Signed-off-by: Yun Peng <[email protected]>

* Remote: Add support for compression on gRPC cache

Add support for compressed transfers from/to gRPC remote caches with flag --experimental_remote_cache_compression.

Fixes #13344.

Closes #14041.

PiperOrigin-RevId: 409328001

Co-authored-by: Alessandro Patti <[email protected]>
@werkt
Copy link
Contributor

werkt commented Nov 20, 2022

So I got up close and personal with this implementation when I added zstd support to buildfarm, per the supplied streams in the zstd package, and I feel this needs to be reworked.

The overall stream is not being compressed for transport in a tidily shorter sequence of upload/download chunks. Instead, each chunk is being compressed and sent as a shorter WriteRequest/ReadResponse. This results in drastically poorer overall byte ratio of identity:compressed compared to a simple zstd invocation on blob content, with a higher possibility of blob inflation due to the reduced context and overhead of the smaller blocks.

This was discovered when the upload went through buildfarm's rechunking mechanism for shards, where request chunks would be combined or split on 16k boundaries by default, and the stream processor only worked on the current chunk, discarding appended bytes, and eliciting decompression corruption.

Overall, this implementation is in conflict with the zstd compressor description in the remote apis, which makes no mention of sequential compressor streams in compressed packed blob content, but instead expects the full content to be deliverable to a compressor engine in a single context.

I'm going to try to adjust this to get a full blob's worth of compression going, with even block sizes and no per-request/response semantics for the stream.

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

Successfully merging this pull request may close these issues.

7 participants