-
Notifications
You must be signed in to change notification settings - Fork 838
Support Snappy compression for gRPC #2940
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
Conversation
fix: cortexproject#2898 Signed-off-by: Wing924 <[email protected]>
Signed-off-by: Wing924 <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your work! It looks good. I've left some comments here and there, but nothing major.
pkg/util/grpcclient/grpcclient.go
Outdated
| func (cfg *Config) Validate(log log.Logger) error { | ||
| if cfg.UseGzipCompression { | ||
| flagext.DeprecatedFlagsUsed.Inc() | ||
| level.Warn(log).Log("msg", "flag *.grpc-use-gzip-compression (or config use_gzip_compression) is deprecated, use *.grpc-use-compression instead.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if it's a good idea, but we could save the prefix in RegisterFlagsWithPrefix, and then report full flag name here.
|
Could you give specific numbers for the benchmarks - looks like a 40% reduction in distributor CPU usage traded for a 150% change in network bandwidth? (comparing gzip and snappy). |
Signed-off-by: Wing924 <[email protected]>
benchmark result
|
|
@pstibrany I've fixed it. Could you review it again? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for addressing my feedback. I have left some more small comments. Can you please take a look?
CHANGELOG.md
Outdated
| * [ENHANCEMENT/CHANGE] Added new flags `-*.grpc-compression` to configure compression used by gRPC. Valid values are "gzip", "snappy", "" (no compression, default). Previous flags (`-*.use-gzip-compression`, enumerate) are now deprecated. #2940 | ||
| * `-bigtable.grpc-compression` | ||
| * `-ingester.client.grpc-compression` | ||
| * `-querier.frontend-client.grpc-compression` | ||
| * Deprecated: `-bigtable.grpc-use-gzip-compression` | ||
| * Deprecated: `-ingester.client.grpc-use-gzip-compression` | ||
| * Deprecated: `-querier.frontend-client.grpc-use-gzip-compression` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| * [ENHANCEMENT/CHANGE] Added new flags `-*.grpc-compression` to configure compression used by gRPC. Valid values are "gzip", "snappy", "" (no compression, default). Previous flags (`-*.use-gzip-compression`, enumerate) are now deprecated. #2940 | |
| * `-bigtable.grpc-compression` | |
| * `-ingester.client.grpc-compression` | |
| * `-querier.frontend-client.grpc-compression` | |
| * Deprecated: `-bigtable.grpc-use-gzip-compression` | |
| * Deprecated: `-ingester.client.grpc-use-gzip-compression` | |
| * Deprecated: `-querier.frontend-client.grpc-use-gzip-compression` | |
| * [ENHANCEMENT] Added new flags `-bigtable.grpc-compression`, `-ingester.client.grpc-compression`, `-querier.frontend-client.grpc-compression` to configure compression used by gRPC. Valid values are `gzip`, `snappy`, or empty string (no compression, default). #2940 | |
| * [CHANGE] Flags `-bigtable.grpc-use-gzip-compression`, `-ingester.client.grpc-use-gzip-compression`, `-querier.frontend-client.grpc-use-gzip-compression` are now deprecated. #2940 |
(Note that they should be moved to their respective sections)
| *compressor | ||
| *snappy.Writer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to avoid nameless embeds. They expose more methods than intended (writeCloser now has methods like Name and Compress), and may inadvertently implement methods that were not meant to be implemented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment applies to reader.
pkg/util/grpcclient/grpcclient.go
Outdated
| func (cfg *Config) Validate(log log.Logger) error { | ||
| if cfg.UseGzipCompression { | ||
| flagext.DeprecatedFlagsUsed.Inc() | ||
| level.Warn(log).Log("msg", fmt.Sprintf("running with DEPRECATED flag -%s.grpc-use-gzip-compression, use -%s.grpc-use-compression instead.", cfg.prefix, cfg.prefix)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be ... use -%s.grpc-compression now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing job, thanks! I left few comments (other than Peter's ones) but I believe we're on a very good track 👏
pkg/util/grpcclient/grpcclient.go
Outdated
| MaxRecvMsgSize int `yaml:"max_recv_msg_size"` | ||
| MaxSendMsgSize int `yaml:"max_send_msg_size"` | ||
| UseGzipCompression bool `yaml:"use_gzip_compression"` | ||
| Compression string `yaml:"compression"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CLI flags and YAML config option names should match.
| Compression string `yaml:"compression"` | |
| Compression string `yaml:"grpc_compression"` |
pkg/util/grpcclient/grpcclient.go
Outdated
| level.Warn(log).Log("msg", fmt.Sprintf("running with DEPRECATED flag -%s.grpc-use-gzip-compression, use -%s.grpc-use-compression instead.", cfg.prefix, cfg.prefix)) | ||
| } | ||
| switch cfg.Compression { | ||
| case "gzip", "snappy", "": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would use snappy.Name instead of the hardcoded "snappy" given we have the constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this made me go back and look why I didn't use gzip.Name, and it turns out it didn't exist at the time.
| *compressor | ||
| *snappy.Writer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment applies to reader.
| return errors.Wrap(err, "invalid Cassandra Storage config") | ||
| } | ||
| if err := cfg.GCPStorageConfig.Validate(util.Logger); err != nil { | ||
| return errors.Wrap(err, "invalid GCP Storage Storage config") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return errors.Wrap(err, "invalid GCP Storage Storage config") | |
| return errors.Wrap(err, "invalid GCP Storage config") |
Signed-off-by: Wing924 <[email protected]>
Signed-off-by: Wing924 <[email protected]>
Signed-off-by: Wing924 <[email protected]>
Signed-off-by: Wing924 <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for addressing my feedback.
| func (r *reader) Read(p []byte) (n int, err error) { | ||
| n, err = r.Reader.Read(p) | ||
| if err == io.EOF { | ||
| r.pool.Put(r) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: should we reset snappy.Reader with nil reader before putting back to pool? (same for writer) It would be little more correct to avoid keeping reference to just-read underlying reader, but likely not a big problem as they will be reused all the time.
| } | ||
|
|
||
| type reader struct { | ||
| *snappy.Reader |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: These anonymous embeds now expose snappy.Reader methods. It doesn't even bring anything, as Read is fully reimplemented by reader. In writeCloser it saves reimplementing Write method, although I would still prefer to be explicit. Not a blocker for merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice job! I have last few comments (+ Peter's nits) and then we're good to go 🚀
| # Use compression when sending messages. Supported values are: 'gzip', | ||
| # 'snappy' and '' (disable compression) | ||
| # CLI flag: -bigtable.grpc-compression | ||
| [compression: <string> | default = ""] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect this to be grpc_compression. I'm not sure why the CI linter passed. Could you run make doc again, please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as you may know, CI don't run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I haven't noticed! Can't understand why the CI is not running on this specific PR 👀
pkg/util/grpcclient/grpcclient.go
Outdated
| compression := cfg.GRPCCompression | ||
| if cfg.UseGzipCompression { | ||
| opts = append(opts, grpc.UseCompressor("gzip")) | ||
| compression = "gzip" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| compression = "gzip" | |
| compression = gzip.Name |
pkg/util/grpcclient/grpcclient.go
Outdated
| type Config struct { | ||
| MaxRecvMsgSize int `yaml:"max_recv_msg_size"` | ||
| MaxSendMsgSize int `yaml:"max_send_msg_size"` | ||
| UseGzipCompression bool `yaml:"use_gzip_compression"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| UseGzipCompression bool `yaml:"use_gzip_compression"` | |
| UseGzipCompression bool `yaml:"use_gzip_compression"` // TODO: Remove this deprecated option in v1.6.0. |
Signed-off-by: Wing924 <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why, but CI is not running on this PR. I'm falling it as "request changes" because we need to get the CI pass before merging.
Signed-off-by: Wing924 <[email protected]>
2f15674 to
47d77a0
Compare
I've found the issue. Your PR description contained some characters FYI, I've rebased the last commit to reword the commit message by 1 character and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! One final nit and we should be good to go 😎
Signed-off-by: Wing924 <[email protected]>
|
Thank you! |
What this PR does:
Add snappy compression for gRPC.
Which issue(s) this PR fixes:
Fixes #2898
Checklist
CHANGELOG.mdupdated - the order of entries should be[CHANGE],[FEATURE],[ENHANCEMENT],[BUGFIX]